(* * Copyright (c) 2015-2021 "Neo Technology," * Network Engine for Objects in Lund AB [http://neotechnology.com] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Attribution Notice under the terms of the Apache License 2.0 * * This work was created by the collective efforts of the openCypher community. * Without limiting the terms of Section 6, any Derivative Work that is not * approved by the public consensus process of the openCypher Implementers Group * should not be described as “Cypher” (and Cypher® is a registered trademark of * Neo4j Inc.) or as "openCypher". Extensions by implementers or prototypes or * proposals for change that have been documented or implemented should only be * described as "implementation extensions to Cypher" or as "proposed changes to * Cypher that are not yet approved by the openCypher community". *) Cypher = [SP], Statement, [[SP], ';'], [SP], EOI ; Statement = Query ; Query = RegularQuery | StandaloneCall ; RegularQuery = SingleQuery, { [SP], Union } ; Union = ((U,N,I,O,N), SP, (A,L,L), [SP], SingleQuery) | ((U,N,I,O,N), [SP], SingleQuery) ; SingleQuery = SinglePartQuery | MultiPartQuery ; SinglePartQuery = ({ ReadingClause, [SP] }, Return) | ({ ReadingClause, [SP] }, UpdatingClause, { [SP], UpdatingClause }, [[SP], Return]) ; MultiPartQuery = { { ReadingClause, [SP] }, { UpdatingClause, [SP] }, With, [SP] }-, SinglePartQuery ; UpdatingClause = Create | Merge | Delete | Set | Remove ; ReadingClause = Match | Unwind | InQueryCall ; Match = [(O,P,T,I,O,N,A,L), SP], (M,A,T,C,H), [SP], Pattern, [[SP], Where] ; Unwind = (U,N,W,I,N,D), [SP], Expression, SP, (A,S), SP, Variable ; Merge = (M,E,R,G,E), [SP], PatternPart, { SP, MergeAction } ; MergeAction = ((O,N), SP, (M,A,T,C,H), SP, Set) | ((O,N), SP, (C,R,E,A,T,E), SP, Set) ; Create = (C,R,E,A,T,E), [SP], Pattern ; Set = (S,E,T), [SP], SetItem, { [SP], ',', [SP], SetItem } ; SetItem = (PropertyExpression, [SP], '=', [SP], Expression) | (Variable, [SP], '=', [SP], Expression) | (Variable, [SP], '+=', [SP], Expression) | (Variable, [SP], NodeLabels) ; Delete = [(D,E,T,A,C,H), SP], (D,E,L,E,T,E), [SP], Expression, { [SP], ',', [SP], Expression } ; Remove = (R,E,M,O,V,E), SP, RemoveItem, { [SP], ',', [SP], RemoveItem } ; RemoveItem = (Variable, NodeLabels) | PropertyExpression ; InQueryCall = (C,A,L,L), SP, ExplicitProcedureInvocation, [[SP], (Y,I,E,L,D), SP, YieldItems] ; StandaloneCall = (C,A,L,L), SP, (ExplicitProcedureInvocation | ImplicitProcedureInvocation), [[SP], (Y,I,E,L,D), SP, ('*' | YieldItems)] ; YieldItems = YieldItem, { [SP], ',', [SP], YieldItem }, [[SP], Where] ; YieldItem = [ProcedureResultField, SP, (A,S), SP], Variable ; With = (W,I,T,H), ProjectionBody, [[SP], Where] ; Return = (R,E,T,U,R,N), ProjectionBody ; ProjectionBody = [[SP], (D,I,S,T,I,N,C,T)], SP, ProjectionItems, [SP, Order], [SP, Skip], [SP, Limit] ; ProjectionItems = ('*', { [SP], ',', [SP], ProjectionItem }) | (ProjectionItem, { [SP], ',', [SP], ProjectionItem }) ; ProjectionItem = (Expression, SP, (A,S), SP, Variable) | Expression ; Order = (O,R,D,E,R), SP, (B,Y), SP, SortItem, { ',', [SP], SortItem } ; Skip = (S,K,I,P), SP, Expression ; Limit = (L,I,M,I,T), SP, Expression ; SortItem = Expression, [[SP], ((A,S,C,E,N,D,I,N,G) | (A,S,C) | (D,E,S,C,E,N,D,I,N,G) | (D,E,S,C))] ; Where = (W,H,E,R,E), SP, Expression ; Pattern = PatternPart, { [SP], ',', [SP], PatternPart } ; PatternPart = (Variable, [SP], '=', [SP], AnonymousPatternPart) | AnonymousPatternPart ; AnonymousPatternPart = PatternElement ; PatternElement = (NodePattern, { [SP], PatternElementChain }) | ('(', PatternElement, ')') ; NodePattern = '(', [SP], [Variable, [SP]], [NodeLabels, [SP]], [Properties, [SP]], ')' ; PatternElementChain = RelationshipPattern, [SP], NodePattern ; RelationshipPattern = (LeftArrowHead, [SP], Dash, [SP], [RelationshipDetail], [SP], Dash, [SP], RightArrowHead) | (LeftArrowHead, [SP], Dash, [SP], [RelationshipDetail], [SP], Dash) | (Dash, [SP], [RelationshipDetail], [SP], Dash, [SP], RightArrowHead) | (Dash, [SP], [RelationshipDetail], [SP], Dash) ; RelationshipDetail = '[', [SP], [Variable, [SP]], [RelationshipTypes, [SP]], [RangeLiteral], [Properties, [SP]], ']' ; Properties = MapLiteral | Parameter ; RelationshipTypes = ':', [SP], RelTypeName, { [SP], '|', [':'], [SP], RelTypeName } ; NodeLabels = NodeLabel, { [SP], NodeLabel } ; NodeLabel = ':', [SP], LabelName ; RangeLiteral = '*', [SP], [IntegerLiteral, [SP]], ['..', [SP], [IntegerLiteral, [SP]]] ; LabelName = SchemaName ; RelTypeName = SchemaName ; Expression = OrExpression ; OrExpression = XorExpression, { SP, (O,R), SP, XorExpression } ; XorExpression = AndExpression, { SP, (X,O,R), SP, AndExpression } ; AndExpression = NotExpression, { SP, (A,N,D), SP, NotExpression } ; NotExpression = { (N,O,T), [SP] }, ComparisonExpression ; ComparisonExpression = AddOrSubtractExpression, { [SP], PartialComparisonExpression } ; AddOrSubtractExpression = MultiplyDivideModuloExpression, { ([SP], '+', [SP], MultiplyDivideModuloExpression) | ([SP], '-', [SP], MultiplyDivideModuloExpression) } ; MultiplyDivideModuloExpression = PowerOfExpression, { ([SP], '*', [SP], PowerOfExpression) | ([SP], '/', [SP], PowerOfExpression) | ([SP], '%', [SP], PowerOfExpression) } ; PowerOfExpression = UnaryAddOrSubtractExpression, { [SP], '^', [SP], UnaryAddOrSubtractExpression } ; UnaryAddOrSubtractExpression = { ('+' | '-'), [SP] }, StringListNullOperatorExpression ; StringListNullOperatorExpression = PropertyOrLabelsExpression, { StringOperatorExpression | ListOperatorExpression | NullOperatorExpression } ; ListOperatorExpression = (SP, (I,N), [SP], PropertyOrLabelsExpression) | ([SP], '[', Expression, ']') | ([SP], '[', [Expression], '..', [Expression], ']') ; StringOperatorExpression = ((SP, (S,T,A,R,T,S), SP, (W,I,T,H)) | (SP, (E,N,D,S), SP, (W,I,T,H)) | (SP, (C,O,N,T,A,I,N,S))), [SP], PropertyOrLabelsExpression ; NullOperatorExpression = (SP, (I,S), SP, (N,U,L,L)) | (SP, (I,S), SP, (N,O,T), SP, (N,U,L,L)) ; PropertyOrLabelsExpression = Atom, { [SP], PropertyLookup }, [[SP], NodeLabels] ; Atom = Literal | Parameter | CaseExpression | ((C,O,U,N,T), [SP], '(', [SP], '*', [SP], ')') | ListComprehension | PatternComprehension | ((A,L,L), [SP], '(', [SP], FilterExpression, [SP], ')') | ((A,N,Y), [SP], '(', [SP], FilterExpression, [SP], ')') | ((N,O,N,E), [SP], '(', [SP], FilterExpression, [SP], ')') | ((S,I,N,G,L,E), [SP], '(', [SP], FilterExpression, [SP], ')') | RelationshipsPattern | ParenthesizedExpression | FunctionInvocation | ExistentialSubquery | Variable ; Literal = NumberLiteral | StringLiteral | BooleanLiteral | (N,U,L,L) | MapLiteral | ListLiteral ; BooleanLiteral = (T,R,U,E) | (F,A,L,S,E) ; ListLiteral = '[', [SP], [Expression, [SP], { ',', [SP], Expression, [SP] }], ']' ; PartialComparisonExpression = ('=', [SP], AddOrSubtractExpression) | ('<>', [SP], AddOrSubtractExpression) | ('<', [SP], AddOrSubtractExpression) | ('>', [SP], AddOrSubtractExpression) | ('<=', [SP], AddOrSubtractExpression) | ('>=', [SP], AddOrSubtractExpression) ; ParenthesizedExpression = '(', [SP], Expression, [SP], ')' ; RelationshipsPattern = NodePattern, { [SP], PatternElementChain }- ; FilterExpression = IdInColl, [[SP], Where] ; IdInColl = Variable, SP, (I,N), SP, Expression ; FunctionInvocation = FunctionName, [SP], '(', [SP], [(D,I,S,T,I,N,C,T), [SP]], [Expression, [SP], { ',', [SP], Expression, [SP] }], ')' ; FunctionName = Namespace, SymbolicName ; ExistentialSubquery = (E,X,I,S,T,S), [SP], '{', [SP], (RegularQuery | (Pattern, [[SP], Where])), [SP], '}' ; ExplicitProcedureInvocation = ProcedureName, [SP], '(', [SP], [Expression, [SP], { ',', [SP], Expression, [SP] }], ')' ; ImplicitProcedureInvocation = ProcedureName ; ProcedureResultField = SymbolicName ; ProcedureName = Namespace, SymbolicName ; Namespace = { SymbolicName, '.' } ; ListComprehension = '[', [SP], FilterExpression, [[SP], '|', [SP], Expression], [SP], ']' ; PatternComprehension = '[', [SP], [Variable, [SP], '=', [SP]], RelationshipsPattern, [SP], [Where, [SP]], '|', [SP], Expression, [SP], ']' ; PropertyLookup = '.', [SP], (PropertyKeyName) ; CaseExpression = (((C,A,S,E), { [SP], CaseAlternative }-) | ((C,A,S,E), [SP], Expression, { [SP], CaseAlternative }-)), [[SP], (E,L,S,E), [SP], Expression], [SP], (E,N,D) ; CaseAlternative = (W,H,E,N), [SP], Expression, [SP], (T,H,E,N), [SP], Expression ; Variable = SymbolicName ; StringLiteral = ('"', { ANY - ('"' | '\') | EscapedChar }, '"') | ("'", { ANY - ("'" | '\') | EscapedChar }, "'") ; EscapedChar = '\', ('\' | "'" | '"' | (B) | (F) | (N) | (R) | (T) | ((U), 4 * HexDigit) | ((U), 8 * HexDigit)) ; NumberLiteral = DoubleLiteral | IntegerLiteral ; MapLiteral = '{', [SP], [PropertyKeyName, [SP], ':', [SP], Expression, [SP], { ',', [SP], PropertyKeyName, [SP], ':', [SP], Expression, [SP] }], '}' ; Parameter = '$', (SymbolicName | DecimalInteger) ; PropertyExpression = Atom, { [SP], PropertyLookup }- ; PropertyKeyName = SchemaName ; IntegerLiteral = HexInteger | OctalInteger | DecimalInteger ; HexInteger = '0x', { HexDigit }- ; DecimalInteger = ZeroDigit | (NonZeroDigit, { Digit }) ; OctalInteger = ZeroDigit, { OctDigit }- ; HexLetter = (A) | (B) | (C) | (D) | (E) | (F) ; HexDigit = Digit | HexLetter ; Digit = ZeroDigit | NonZeroDigit ; NonZeroDigit = NonZeroOctDigit | '8' | '9' ; NonZeroOctDigit = '1' | '2' | '3' | '4' | '5' | '6' | '7' ; OctDigit = ZeroDigit | NonZeroOctDigit ; ZeroDigit = '0' ; DoubleLiteral = ExponentDecimalReal | RegularDecimalReal ; ExponentDecimalReal = ({ Digit }- | ({ Digit }-, '.', { Digit }-) | ('.', { Digit }-)), (E), ['-'], { Digit }- ; RegularDecimalReal = { Digit }, '.', { Digit }- ; SchemaName = SymbolicName | ReservedWord ; ReservedWord = (A,L,L) | (A,S,C) | (A,S,C,E,N,D,I,N,G) | (B,Y) | (C,R,E,A,T,E) | (D,E,L,E,T,E) | (D,E,S,C) | (D,E,S,C,E,N,D,I,N,G) | (D,E,T,A,C,H) | (E,X,I,S,T,S) | (L,I,M,I,T) | (M,A,T,C,H) | (M,E,R,G,E) | (O,N) | (O,P,T,I,O,N,A,L) | (O,R,D,E,R) | (R,E,M,O,V,E) | (R,E,T,U,R,N) | (S,E,T) | (S,K,I,P) | (W,H,E,R,E) | (W,I,T,H) | (U,N,I,O,N) | (U,N,W,I,N,D) | (A,N,D) | (A,S) | (C,O,N,T,A,I,N,S) | (D,I,S,T,I,N,C,T) | (E,N,D,S) | (I,N) | (I,S) | (N,O,T) | (O,R) | (S,T,A,R,T,S) | (X,O,R) | (F,A,L,S,E) | (T,R,U,E) | (N,U,L,L) | (C,O,N,S,T,R,A,I,N,T) | (D,O) | (F,O,R) | (R,E,Q,U,I,R,E) | (U,N,I,Q,U,E) | (C,A,S,E) | (W,H,E,N) | (T,H,E,N) | (E,L,S,E) | (E,N,D) | (M,A,N,D,A,T,O,R,Y) | (S,C,A,L,A,R) | (O,F) | (A,D,D) | (D,R,O,P) ; SymbolicName = UnescapedSymbolicName | EscapedSymbolicName | HexLetter | (C,O,U,N,T) | (F,I,L,T,E,R) | (E,X,T,R,A,C,T) | (A,N,Y) | (N,O,N,E) | (S,I,N,G,L,E) ; UnescapedSymbolicName = IdentifierStart, { IdentifierPart } ; (* Based on the unicode identifier and pattern syntax * (http://www.unicode.org/reports/tr31/) * And extended with a few characters. *)IdentifierStart = ID_Start | Pc ; (* Based on the unicode identifier and pattern syntax * (http://www.unicode.org/reports/tr31/) * And extended with a few characters. *)IdentifierPart = ID_Continue | Sc ; (* Any character except "`", enclosed within `backticks`. Backticks are escaped with double backticks. *)EscapedSymbolicName = { '`', { ANY - ('`') }, '`' }- ; SP = { whitespace }- ; whitespace = SPACE | TAB | LF | VT | FF | CR | FS | GS | RS | US | ' ' | '᠎' | ' ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' ' | '
' | '
' | ' ' | ' ' | ' ' | ' ' | ' ' | Comment ; Comment = ('/*', { ANY - ('*') | ('*', ANY - ('/')) }, '*/') | ('//', { ANY - (LF | CR) }, [CR], (LF | EOI)) ; LeftArrowHead = '<' | '⟨' | '〈' | '﹤' | '<' ; RightArrowHead = '>' | '⟩' | '〉' | '﹥' | '>' ; Dash = '-' | '­' | '‐' | '‑' | '‒' | '–' | '—' | '―' | '−' | '﹘' | '﹣' | '-' ; A = 'A' | 'a' ; B = 'B' | 'b' ; C = 'C' | 'c' ; D = 'D' | 'd' ; E = 'E' | 'e' ; F = 'F' | 'f' ; G = 'G' | 'g' ; H = 'H' | 'h' ; I = 'I' | 'i' ; K = 'K' | 'k' ; L = 'L' | 'l' ; M = 'M' | 'm' ; N = 'N' | 'n' ; O = 'O' | 'o' ; P = 'P' | 'p' ; Q = 'Q' | 'q' ; R = 'R' | 'r' ; S = 'S' | 's' ; T = 'T' | 't' ; U = 'U' | 'u' ; V = 'V' | 'v' ; W = 'W' | 'w' ; X = 'X' | 'x' ; Y = 'Y' | 'y' ;