A XQuery 4.0 Grammar

A.1 EBNF

The grammar of XQuery 4.0 uses the same simple Extended Backus-Naur Form (EBNF) notation as [XML 1.0] with the following minor differences.

The terminal symbols for this grammar include the quoted strings used in the production rules below, and the terminal symbols defined in section A.2.1 Terminal Symbols.

The EBNF notation is described in more detail in A.1.1 Notation.

[1]    Module    ::=    VersionDecl? (LibraryModule | MainModule)
[2]    VersionDecl    ::=    "xquery" (("encoding" StringLiteral) | ("version" StringLiteral ("encoding" StringLiteral)?)) Separator
[3]    MainModule    ::=    Prolog QueryBody
[4]    LibraryModule    ::=    ModuleDecl Prolog
[5]    ModuleDecl    ::=    "module" "namespace" NCName "=" URILiteral Separator
[6]    Prolog    ::=    ((DefaultNamespaceDecl | Setter | NamespaceDecl | Import) Separator)* ((ContextItemDecl | AnnotatedDecl | OptionDecl) Separator)*
[7]    Separator    ::=    ";"
[8]    Setter    ::=    BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | CopyNamespacesDecl | DecimalFormatDecl
[9]    BoundarySpaceDecl    ::=    "declare" "boundary-space" ("preserve" | "strip")
[10]    DefaultCollationDecl    ::=    "declare" "default" "collation" URILiteral
[11]    BaseURIDecl    ::=    "declare" "base-uri" URILiteral
[12]    ConstructionDecl    ::=    "declare" "construction" ("strip" | "preserve")
[13]    OrderingModeDecl    ::=    "declare" "ordering" ("ordered" | "unordered")
[14]    EmptyOrderDecl    ::=    "declare" "default" "order" "empty" ("greatest" | "least")
[15]    CopyNamespacesDecl    ::=    "declare" "copy-namespaces" PreserveMode "," InheritMode
[16]    PreserveMode    ::=    "preserve" | "no-preserve"
[17]    InheritMode    ::=    "inherit" | "no-inherit"
[18]    DecimalFormatDecl    ::=    "declare" (("decimal-format" EQName) | ("default" "decimal-format")) (DFPropertyName "=" StringLiteral)*
[19]    DFPropertyName    ::=    "decimal-separator" | "grouping-separator" | "infinity" | "minus-sign" | "NaN" | "percent" | "per-mille" | "zero-digit" | "digit" | "pattern-separator" | "exponent-separator"
[20]    Import    ::=    SchemaImport | ModuleImport
[21]    SchemaImport    ::=    "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)?
[22]    SchemaPrefix    ::=    ("namespace" NCName "=") | ("default" "element" "namespace")
[23]    ModuleImport    ::=    "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)?
[24]    NamespaceDecl    ::=    "declare" "namespace" NCName "=" URILiteral
[25]    DefaultNamespaceDecl    ::=    "declare" "default" ("element" | "type" | "function") "namespace" URILiteral
[26]    AnnotatedDecl    ::=    "declare" Annotation* (VarDecl | FunctionDecl | ItemTypeDecl)
[27]    Annotation    ::=    "%" EQName ("(" Literal ("," Literal)* ")")?
[28]    VarDecl    ::=    "variable" "$" VarName TypeDeclaration? ((":=" VarValue) | ("external" (":=" VarDefaultValue)?))
[29]    VarValue    ::=    ExprSingle
[30]    VarDefaultValue    ::=    ExprSingle
[31]    ContextItemDecl    ::=    "declare" "context" "item" ("as" ItemType)? ((":=" VarValue) | ("external" (":=" VarDefaultValue)?))
[32]    FunctionDecl    ::=    "function" EQName FunctionSignatureWithDefaults (FunctionBody | "external") /* xgc: reserved-function-names */
[33]    FunctionSignatureWithDefaults    ::=    "(" ParamListWithDefaults? ")" TypeDeclaration?
[34]    FunctionSignature    ::=    "(" ParamList? ")" TypeDeclaration?
[35]    ParamListWithDefaults    ::=    ParamWithDefault ("," ParamWithDefault)*
[36]    ParamWithDefault    ::=    "$" EQName TypeDeclaration? (":=" ExprSingle)?
[37]    ParamList    ::=    Param ("," Param)*
[38]    Param    ::=    "$" EQName TypeDeclaration?
[39]    FunctionBody    ::=    EnclosedExpr
[40]    EnclosedExpr    ::=    "{" Expr? "}"
[41]    ItemTypeDecl    ::=    "item-type" EQName "as" ItemType
[42]    OptionDecl    ::=    "declare" "option" EQName StringLiteral
[43]    QueryBody    ::=    Expr
[44]    Expr    ::=    ExprSingle ("," ExprSingle)*
[45]    ExprSingle    ::=    WithExpr
| FLWORExpr
| QuantifiedExpr
| SwitchExpr
| TypeswitchExpr
| IfExpr
| TryCatchExpr
| TernaryConditionalExpr
[46]    WithExpr    ::=    "with" NamespaceDeclaration ("," NamespaceDeclaration)* EnclosedExpr
[47]    NamespaceDeclaration    ::=    QName "=" URILiteral
[48]    TernaryConditionalExpr    ::=    OrExpr ("??" TernaryConditionalExpr "!!" TernaryConditionalExpr)?
[49]    FLWORExpr    ::=    InitialClause IntermediateClause* ReturnClause
[50]    InitialClause    ::=    ForClause | ForMemberClause | LetClause | WindowClause
[51]    IntermediateClause    ::=    InitialClause | WhereClause | GroupByClause | OrderByClause | CountClause
[52]    ForClause    ::=    "for" ForBinding ("," ForBinding)*
[53]    ForBinding    ::=    "$" VarName TypeDeclaration? AllowingEmpty? PositionalVar? "in" ExprSingle
[54]    AllowingEmpty    ::=    "allowing" "empty"
[55]    ForMemberClause    ::=    "for" "member" ForMemberBinding ("," ForMemberBinding)*
[56]    ForMemberBinding    ::=    "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle
[57]    PositionalVar    ::=    "at" "$" VarName
[58]    LetClause    ::=    "let" LetBinding ("," LetBinding)*
[59]    LetBinding    ::=    "$" VarName TypeDeclaration? ":=" ExprSingle
[60]    WindowClause    ::=    "for" (TumblingWindowClause | SlidingWindowClause)
[61]    TumblingWindowClause    ::=    "tumbling" "window" "$" VarName TypeDeclaration? "in" ExprSingle WindowStartCondition WindowEndCondition?
[62]    SlidingWindowClause    ::=    "sliding" "window" "$" VarName TypeDeclaration? "in" ExprSingle WindowStartCondition WindowEndCondition
[63]    WindowStartCondition    ::=    "start" WindowVars "when" ExprSingle
[64]    WindowEndCondition    ::=    "only"? "end" WindowVars "when" ExprSingle
[65]    WindowVars    ::=    ("$" CurrentItem)? PositionalVar? ("previous" "$" PreviousItem)? ("next" "$" NextItem)?
[66]    CurrentItem    ::=    EQName
[67]    PreviousItem    ::=    EQName
[68]    NextItem    ::=    EQName
[69]    CountClause    ::=    "count" "$" VarName
[70]    WhereClause    ::=    "where" ExprSingle
[71]    GroupByClause    ::=    "group" "by" GroupingSpecList
[72]    GroupingSpecList    ::=    GroupingSpec ("," GroupingSpec)*
[73]    GroupingSpec    ::=    GroupingVariable (TypeDeclaration? ":=" ExprSingle)? ("collation" URILiteral)?
[74]    GroupingVariable    ::=    "$" VarName
[75]    OrderByClause    ::=    (("order" "by") | ("stable" "order" "by")) OrderSpecList
[76]    OrderSpecList    ::=    OrderSpec ("," OrderSpec)*
[77]    OrderSpec    ::=    ExprSingle OrderModifier
[78]    OrderModifier    ::=    ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)?
[79]    ReturnClause    ::=    "return" ExprSingle
[80]    QuantifiedExpr    ::=    ("some" | "every") QuantifierBinding ("," QuantifierBinding)* "satisfies" ExprSingle
[81]    QuantifierBinding    ::=    "$" VarName TypeDeclaration? "in" ExprSingle
[82]    SwitchExpr    ::=    "switch" "(" Expr ")" SwitchCaseClause+ "default" "return" ExprSingle
[83]    SwitchCaseClause    ::=    ("case" SwitchCaseOperand)+ "return" ExprSingle
[84]    SwitchCaseOperand    ::=    ExprSingle
[85]    TypeswitchExpr    ::=    "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle
[86]    CaseClause    ::=    "case" ("$" VarName "as")? SequenceTypeUnion "return" ExprSingle
[87]    SequenceTypeUnion    ::=    SequenceType ("|" SequenceType)*
[88]    IfExpr    ::=    "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
[89]    TryCatchExpr    ::=    TryClause CatchClause+
[90]    TryClause    ::=    "try" EnclosedTryTargetExpr
[91]    EnclosedTryTargetExpr    ::=    EnclosedExpr
[92]    CatchClause    ::=    "catch" CatchErrorList EnclosedExpr
[93]    CatchErrorList    ::=    NameTest ("|" NameTest)*
[94]    OrExpr    ::=    AndExpr ( "or" AndExpr )*
[95]    AndExpr    ::=    ComparisonExpr ( "and" ComparisonExpr )*
[96]    ComparisonExpr    ::=    StringConcatExpr ( (ValueComp
| GeneralComp
| NodeComp) StringConcatExpr )?
[97]    StringConcatExpr    ::=    RangeExpr ( "||" RangeExpr )*
[98]    RangeExpr    ::=    AdditiveExpr ( "to" AdditiveExpr )?
[99]    AdditiveExpr    ::=    MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*
[100]    MultiplicativeExpr    ::=    OtherwiseExpr ( ("*" | "div" | "idiv" | "mod") OtherwiseExpr )*
[101]    OtherwiseExpr    ::=    UnionExpr ( "otherwise" UnionExpr )*
[102]    UnionExpr    ::=    IntersectExceptExpr ( ("union" | "|") IntersectExceptExpr )*
[103]    IntersectExceptExpr    ::=    InstanceofExpr ( ("intersect" | "except") InstanceofExpr )*
[104]    InstanceofExpr    ::=    TreatExpr ( "instance" "of" SequenceType )?
[105]    TreatExpr    ::=    CastableExpr ( "treat" "as" SequenceType )?
[106]    CastableExpr    ::=    CastExpr ( "castable" "as" SingleType )?
[107]    CastExpr    ::=    ArrowExpr ( "cast" "as" SingleType )?
[108]    ArrowExpr    ::=    UnaryExpr ( (FatArrowTarget | ThinArrowTarget) )*
[109]    UnaryExpr    ::=    ("-" | "+")* ValueExpr
[110]    ValueExpr    ::=    ValidateExpr | ExtensionExpr | SimpleMapExpr
[111]    FatArrowTarget    ::=    "=>" ((ArrowStaticFunction ArgumentList) | (ArrowDynamicFunction PositionalArgumentList))
[112]    ThinArrowTarget    ::=    "->" ((ArrowStaticFunction ArgumentList) | (ArrowDynamicFunction PositionalArgumentList) | EnclosedExpr)
[113]    GeneralComp    ::=    "=" | "!=" | "<" | "<=" | ">" | ">="
[114]    ValueComp    ::=    "eq" | "ne" | "lt" | "le" | "gt" | "ge"
[115]    NodeComp    ::=    "is" | "<<" | ">>"
[116]    ValidateExpr    ::=    "validate" (ValidationMode | ("type" TypeName))? "{" Expr "}"
[117]    ValidationMode    ::=    "lax" | "strict"
[118]    ExtensionExpr    ::=    Pragma+ "{" Expr? "}"
[119]    Pragma    ::=    "(#" S? EQName (S PragmaContents)? "#)" /* ws: explicit */
[120]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))
[121]    SimpleMapExpr    ::=    PathExpr ("!" PathExpr)*
[122]    PathExpr    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
/* xgc: leading-lone-slash */
[123]    RelativePathExpr    ::=    StepExpr (("/" | "//") StepExpr)*
[124]    StepExpr    ::=    PostfixExpr | AxisStep
[125]    AxisStep    ::=    (ReverseStep | ForwardStep) PredicateList
[126]    ForwardStep    ::=    (ForwardAxis NodeTest) | AbbrevForwardStep
[127]    ForwardAxis    ::=    ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
[128]    AbbrevForwardStep    ::=    "@"? NodeTest
[129]    ReverseStep    ::=    (ReverseAxis NodeTest) | AbbrevReverseStep
[130]    ReverseAxis    ::=    ("parent" "::")
| ("ancestor" "::")
| ("preceding-sibling" "::")
| ("preceding" "::")
| ("ancestor-or-self" "::")
[131]    AbbrevReverseStep    ::=    ".."
[132]    NodeTest    ::=    KindTest | NameTest
[133]    NameTest    ::=    EQName | Wildcard
[134]    Wildcard    ::=    "*"
| (NCName ":*")
| ("*:" NCName)
| (BracedURILiteral "*")
/* ws: explicit */
[135]    PostfixExpr    ::=    PrimaryExpr (Predicate | PositionalArgumentList | Lookup)*
[136]    ArgumentList    ::=    "(" ((PositionalArguments ("," KeywordArguments)?) | KeywordArguments)? ")"
[137]    PositionalArgumentList    ::=    "(" PositionalArguments? ")"
[138]    PositionalArguments    ::=    Argument ("," Argument)*
[139]    KeywordArguments    ::=    KeywordArgument ("," KeywordArgument)*
[140]    KeywordArgument    ::=    EQName ":=" Argument
[141]    PredicateList    ::=    Predicate*
[142]    Predicate    ::=    "[" Expr "]"
[143]    Lookup    ::=    "?" KeySpecifier
[144]    KeySpecifier    ::=    NCName | IntegerLiteral | StringLiteral | VarRef | ParenthesizedExpr | "*"
[145]    ArrowStaticFunction    ::=    EQName
[146]    ArrowDynamicFunction    ::=    VarRef | ParenthesizedExpr
[147]    PrimaryExpr    ::=    Literal
| VarRef
| ParenthesizedExpr
| ContextItemExpr
| FunctionCall
| OrderedExpr
| UnorderedExpr
| NodeConstructor
| FunctionItemExpr
| MapConstructor
| ArrayConstructor
| StringConstructor
| UnaryLookup
[148]    Literal    ::=    NumericLiteral | StringLiteral
[149]    NumericLiteral    ::=    IntegerLiteral | DecimalLiteral | DoubleLiteral
[150]    VarRef    ::=    "$" VarName
[151]    VarName    ::=    EQName
[152]    ParenthesizedExpr    ::=    "(" Expr? ")"
[153]    ContextItemExpr    ::=    "."
[154]    OrderedExpr    ::=    "ordered" EnclosedExpr
[155]    UnorderedExpr    ::=    "unordered" EnclosedExpr
[156]    FunctionCall    ::=    EQName ArgumentList /* xgc: reserved-function-names */
/* gn: parens */
[157]    Argument    ::=    ExprSingle | ArgumentPlaceholder
[158]    ArgumentPlaceholder    ::=    "?"
[159]    NodeConstructor    ::=    DirectConstructor
| ComputedConstructor
[160]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[161]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">")) /* ws: explicit */
[162]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)* /* ws: explicit */
[163]    DirAttributeValue    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
/* ws: explicit */
[164]    QuotAttrValueContent    ::=    QuotAttrContentChar
| CommonContent
[165]    AposAttrValueContent    ::=    AposAttrContentChar
| CommonContent
[166]    DirElemContent    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[167]    CommonContent    ::=    PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr
[168]    DirCommentConstructor    ::=    "<!--" DirCommentContents "-->" /* ws: explicit */
[169]    DirCommentContents    ::=    ((Char - '-') | ('-' (Char - '-')))* /* ws: explicit */
[170]    DirPIConstructor    ::=    "<?" PITarget (S DirPIContents)? "?>" /* ws: explicit */
[171]    DirPIContents    ::=    (Char* - (Char* '?>' Char*)) /* ws: explicit */
[172]    CDataSection    ::=    "<![CDATA[" CDataSectionContents "]]>" /* ws: explicit */
[173]    CDataSectionContents    ::=    (Char* - (Char* ']]>' Char*)) /* ws: explicit */
[174]    ComputedConstructor    ::=    CompDocConstructor
| CompElemConstructor
| CompAttrConstructor
| CompNamespaceConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
[175]    CompDocConstructor    ::=    "document" EnclosedExpr
[176]    CompElemConstructor    ::=    "element" (EQName | ("{" Expr "}")) EnclosedContentExpr
[177]    EnclosedContentExpr    ::=    EnclosedExpr
[178]    CompAttrConstructor    ::=    "attribute" (EQName | ("{" Expr "}")) EnclosedExpr
[179]    CompNamespaceConstructor    ::=    "namespace" (Prefix | EnclosedPrefixExpr) EnclosedURIExpr
[180]    Prefix    ::=    NCName
[181]    EnclosedPrefixExpr    ::=    EnclosedExpr
[182]    EnclosedURIExpr    ::=    EnclosedExpr
[183]    CompTextConstructor    ::=    "text" EnclosedExpr
[184]    CompCommentConstructor    ::=    "comment" EnclosedExpr
[185]    CompPIConstructor    ::=    "processing-instruction" (NCName | ("{" Expr "}")) EnclosedExpr
[186]    FunctionItemExpr    ::=    NamedFunctionRef | InlineFunctionExpr
[187]    NamedFunctionRef    ::=    EQName "#" IntegerLiteral /* xgc: reserved-function-names */
[188]    InlineFunctionExpr    ::=    Annotation* (("function" FunctionSignature) | ("->" FunctionSignature?)) FunctionBody
[189]    MapConstructor    ::=    "map" "{" (MapConstructorEntry ("," MapConstructorEntry)*)? "}"
[190]    MapConstructorEntry    ::=    MapKeyExpr ":" MapValueExpr
[191]    MapKeyExpr    ::=    ExprSingle
[192]    MapValueExpr    ::=    ExprSingle
[193]    ArrayConstructor    ::=    SquareArrayConstructor | CurlyArrayConstructor
[194]    SquareArrayConstructor    ::=    "[" (ExprSingle ("," ExprSingle)*)? "]"
[195]    CurlyArrayConstructor    ::=    "array" EnclosedExpr
[196]    StringConstructor    ::=    "``[" StringConstructorContent "]``" /* ws: explicit */
[197]    StringConstructorContent    ::=    StringConstructorChars (StringConstructorInterpolation StringConstructorChars)* /* ws: explicit */
[198]    StringConstructorChars    ::=    (Char* - (Char* ('`{' | ']``') Char*)) /* ws: explicit */
[199]    StringConstructorInterpolation    ::=    "`{" Expr? "}`"
[200]    UnaryLookup    ::=    "?" KeySpecifier
[201]    SingleType    ::=    SimpleTypeName "?"?
[202]    TypeDeclaration    ::=    "as" SequenceType
[203]    SequenceType    ::=    ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
[204]    OccurrenceIndicator    ::=    "?" | "*" | "+" /* xgc: occurrence-indicators */
[205]    ItemType    ::=    AnyItemTest | TypeName | KindTest | FunctionTest | MapTest | ArrayTest | AtomicOrUnionType | RecordTest | LocalUnionType | EnumerationType | ParenthesizedItemType
[206]    AnyItemTest    ::=    "item" "(" ")"
[207]    AtomicOrUnionType    ::=    EQName
[208]    KindTest    ::=    DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| NamespaceNodeTest
| AnyKindTest
[209]    AnyKindTest    ::=    "node" "(" ")"
[210]    DocumentTest    ::=    "document-node" "(" (ElementTest | SchemaElementTest)? ")"
[211]    TextTest    ::=    "text" "(" ")"
[212]    CommentTest    ::=    "comment" "(" ")"
[213]    NamespaceNodeTest    ::=    "namespace-node" "(" ")"
[214]    PITest    ::=    "processing-instruction" "(" (NCName | StringLiteral)? ")"
[215]    AttributeTest    ::=    "attribute" "(" (NameTest ("," TypeName)?)? ")"
[216]    SchemaAttributeTest    ::=    "schema-attribute" "(" AttributeDeclaration ")"
[217]    AttributeDeclaration    ::=    AttributeName
[218]    ElementTest    ::=    "element" "(" (NameTest ("," TypeName "?"?)?)? ")"
[219]    SchemaElementTest    ::=    "schema-element" "(" ElementDeclaration ")"
[220]    ElementDeclaration    ::=    ElementName
[221]    AttributeName    ::=    EQName
[222]    ElementName    ::=    EQName
[223]    SimpleTypeName    ::=    TypeName | LocalUnionType
[224]    TypeName    ::=    EQName
[225]    FunctionTest    ::=    Annotation* (AnyFunctionTest
| TypedFunctionTest)
[226]    AnyFunctionTest    ::=    "function" "(" "*" ")"
[227]    TypedFunctionTest    ::=    "function" "(" (SequenceType ("," SequenceType)*)? ")" "as" SequenceType
[228]    MapTest    ::=    AnyMapTest | TypedMapTest
[229]    AnyMapTest    ::=    "map" "(" "*" ")"
[230]    TypedMapTest    ::=    "map" "(" ItemType "," SequenceType ")"
[231]    RecordTest    ::=    "record" "(" FieldDeclaration ("," FieldDeclaration)* ExtensibleFlag? ")"
[232]    FieldDeclaration    ::=    FieldName "?"? ("as" (SequenceType | SelfReference))?
[233]    FieldName    ::=    NCName | StringLiteral
[234]    SelfReference    ::=    ".." OccurrenceIndicator?
[235]    ExtensibleFlag    ::=    "," "*"
[236]    LocalUnionType    ::=    "union" "(" ItemType ("," ItemType)* ")"
[237]    EnumerationType    ::=    "enum" "(" StringLiteral ("," StringLiteral)* ")"
[238]    ArrayTest    ::=    AnyArrayTest | TypedArrayTest
[239]    AnyArrayTest    ::=    "array" "(" "*" ")"
[240]    TypedArrayTest    ::=    "array" "(" SequenceType ")"
[241]    ParenthesizedItemType    ::=    "(" ItemType ")"
[242]    URILiteral    ::=    StringLiteral
[243]    EQName    ::=    QName | URIQualifiedName

A.1.1 Notation

[Definition: Each rule in the grammar defines one symbol, using the following format:

symbol ::= expression

]

[Definition: A terminal is a symbol or string or pattern that can appear in the right-hand side of a rule, but never appears on the left-hand side in the main grammar, although it may appear on the left-hand side of a rule in the grammar for terminals.] The following constructs are used to match strings of one or more characters in a terminal:

[a-zA-Z]

matches any Char with a value in the range(s) indicated (inclusive).

[abc]

matches any Char with a value among the characters enumerated.

[^abc]

matches any Char with a value not among the characters given.

"string"

matches the sequence of characters that appear inside the double quotes.

'string'

matches the sequence of characters that appear inside the single quotes.

[http://www.w3.org/TR/REC-example/#NT-Example]

matches any string matched by the production defined in the external specification as per the provided reference.

Patterns (including the above constructs) can be combined with grammatical operators to form more complex patterns, matching more complex sets of character strings. In the examples that follow, A and B represent (sub-)patterns.

(A)

A is treated as a unit and may be combined as described in this list.

A?

matches A or nothing; optional A.

A B

matches A followed by B. This operator has higher precedence than alternation; thus A B | C D is identical to (A B) | (C D).

A | B

matches A or B but not both.

A - B

matches any string that matches A but does not match B.

A+

matches one or more occurrences of A. Concatenation has higher precedence than alternation; thus A+ | B+ is identical to (A+) | (B+).

A*

matches zero or more occurrences of A. Concatenation has higher precedence than alternation; thus A* | B* is identical to (A*) | (B*)

A.1.2 Extra-grammatical Constraints

This section contains constraints on the EBNF productions, which are required to parse syntactically valid sentences. The notes below are referenced from the right side of the production, with the notation: /* xgc: <id> */.

Constraint: leading-lone-slash

A single slash may appear either as a complete path expression or as the first part of a path expression in which it is followed by a RelativePathExpr. In some cases, the next token after the slash is insufficient to allow a parser to distinguish these two possibilities: the * token and keywords like union could be either an operator or a NameTest , and the < token could be either an operator or the start of a DirectConstructor . For example, without lookahead the first part of the expression / * 5 is easily taken to be a complete expression, / *, which has a very different interpretation (the child nodes of /).

If the token immediately following a slash can form the start of a RelativePathExpr, then the slash must be the beginning of a PathExpr, not the entirety of it.

A single slash may be used as the left-hand argument of an operator by parenthesizing it: (/) * 5. The expression 5 * /, on the other hand, is syntactically valid without parentheses.

Constraint: xml-version

The version of XML and XML Names (e.g. [XML 1.0] and [XML Names], or [XML 1.1] and [XML Names 1.1]) is implementation-defined. It is recommended that the latest applicable version be used (even if it is published later than this specification). The EBNF in this specification links only to the 1.0 versions. Note also that these external productions follow the whitespace rules of their respective specifications, and not the rules of this specification, in particular A.2.4.1 Default Whitespace Handling. Thus prefix : localname is not a syntactically valid lexical QName for purposes of this specification, just as it is not permitted in a XML document. Also, comments are not permissible on either side of the colon. Also extra-grammatical constraints such as well-formedness constraints must be taken into account.

XML 1.0 and XML 1.1 differ in their handling of C0 control characters (specifically #x1 through #x1F, excluding #x9, #xA, and #xD) and C1 control characters (#x7F through #x9F). In XML 1.0, these C0 characters are prohibited, and the C1 characters are permitted. In XML 1.1, both sets of control characters are permitted, but only if written as character references. It is RECOMMENDED that implementations should follow the XML 1.1 rules in this respect; however, for backwards compatibility with XQuery 1.0 , implementations MAY allow C1 control characters to be used directly.

Note:

Direct use of C1 control characters often suggests a character encoding error, such as using encoding CP-1252 and mislabeling it as iso-8859-1.

Constraint: reserved-function-names

Unprefixed function names spelled the same way as language keywords could make the language impossible to parse. For instance, element(foo) could be taken either as a FunctionCall or as an ElementTest. Therefore, an unprefixed function name must not be any of the names in A.3 Reserved Function Names.

A function named "if" can be called by binding its namespace to a prefix and using the prefixed form: "library:if(foo)" instead of "if(foo)".

Constraint: occurrence-indicators

As written, the grammar in A XQuery 4.0 Grammar is ambiguous for some forms using the '+' and '*' occurrence indicators. The ambiguity is resolved as follows: these operators are tightly bound to the SequenceType expression, and have higher precedence than other uses of these symbols. Any occurrence of '+' and '*', as well as '?', following a sequence type is assumed to be an occurrence indicator, which binds to the last ItemType in the SequenceType.

Thus, 4 treat as item() + - 5 must be interpreted as (4 treat as item()+) - 5, taking the '+' as an OccurrenceIndicator and the '-' as a subtraction operator. To force the interpretation of "+" as an addition operator (and the corresponding interpretation of the "-" as a unary minus), parentheses may be used: the form (4 treat as item()) + -5 surrounds the SequenceType expression with parentheses and leads to the desired interpretation.

function () as xs:string * is interpreted as function () as (xs:string *), not as (function () as xs:string) *. Parentheses can be used as shown to force the latter interpretation.

This rule has as a consequence that certain forms which would otherwise be syntactically valid and unambiguous are not recognized: in "4 treat as item() + 5", the "+" is taken as an OccurrenceIndicator, and not as an operator, which means this is not a syntactically valid expression.

A.1.3 Grammar Notes

This section contains general notes on the EBNF productions, which may be helpful in understanding how to interpret and implement the EBNF. These notes are not normative. The notes below are referenced from the right side of the production, with the notation: /* gn: <id> */.

Note:

grammar-note: parens

Look-ahead is required to distinguish FunctionCall from a EQName or keyword followed by a Pragma or Comment. For example: address (: this may be empty :) may be mistaken for a call to a function named "address" unless this lookahead is employed. Another example is for (: whom the bell :) $tolls in 3 return $tolls, where the keyword "for" must not be mistaken for a function name.

grammar-note: comments

Comments are allowed everywhere that ignorable whitespace is allowed, and the Comment symbol does not explicitly appear on the right-hand side of the grammar (except in its own production). See A.2.4.1 Default Whitespace Handling. Note that comments are not allowed in direct constructor content, though they are allowed in nested EnclosedExprs.

A comment can contain nested comments, as long as all "(:" and ":)" patterns are balanced, no matter where they occur within the outer comment.

Note:

Lexical analysis may typically handle nested comments by incrementing a counter for each "(:" pattern, and decrementing the counter for each ":)" pattern. The comment does not terminate until the counter is back to zero.

Some illustrative examples:

  • (: commenting out a (: comment :) may be confusing, but often helpful :) is a syntactically valid Comment, since balanced nesting of comments is allowed.

  • "this is just a string :)" is a syntactically valid expression. However, (: "this is just a string :)" :) will cause a syntax error. Likewise, "this is another string (:" is a syntactically valid expression, but (: "this is another string (:" :) will cause a syntax error. It is a limitation of nested comments that literal content can cause unbalanced nesting of comments.

  • for (: set up loop :) $i in $x return $i is syntactically valid, ignoring the comment.

  • 5 instance (: strange place for a comment :) of xs:integer is also syntactically valid.

  • <eg (: an example:)>{$i//title}</eg> is not syntactically valid.

  • <eg> (: an example:) </eg> is syntactically valid, but the characters that look like a comment are in fact literal element content.

A.2 Lexical structure

The terminal symbols assumed by the grammar above are described in this section.

Quoted strings appearing in production rules are terminal symbols.

Other terminal symbols are defined in A.2.1 Terminal Symbols.

Some productions are defined by reference to the XML and XML Names specifications (e.g. [XML 1.0] and [XML Names], or [XML 1.1] and [XML Names 1.1] . It is implementation-defined which version of these specifications is used; it is recommended that the latest applicable version be used (even if it is published later than this specification).

It is implementation-defined whether the lexical rules of [XML 1.0] and [XML Names] are followed, or alternatively, the lexical rules of [XML 1.1] and [XML Names 1.1] are followed. Implementations that support the full [XML 1.1] character set SHOULD, for purposes of interoperability, provide a mode that follows only the [XML 1.0] and [XML Names] lexical rules.

When tokenizing, the longest possible match that is consistent with the EBNF is used.

All keywords are case sensitive. Keywords are not reserved—that is, any lexical QName may duplicate a keyword except as noted in A.3 Reserved Function Names.

A.2.1 Terminal Symbols

[244]    IntegerLiteral    ::=    Digits
[245]    DecimalLiteral    ::=    ("." Digits) | (Digits "." [0-9]*) /* ws: explicit */
[246]    DoubleLiteral    ::=    (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits /* ws: explicit */
[247]    StringLiteral    ::=    ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'") /* ws: explicit */
[248]    URIQualifiedName    ::=    BracedURILiteral NCName /* ws: explicit */
[249]    BracedURILiteral    ::=    "Q" "{" (PredefinedEntityRef | CharRef | [^&{}])* "}" /* ws: explicit */
[250]    PredefinedEntityRef    ::=    "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";" /* ws: explicit */
[251]    EscapeQuot    ::=    '""'
[252]    EscapeApos    ::=    "''"
[253]    ElementContentChar    ::=    (Char - [{}<&])
[254]    QuotAttrContentChar    ::=    (Char - ["{}<&])
[255]    AposAttrContentChar    ::=    (Char - ['{}<&])
[256]    Comment    ::=    "(:" (CommentContents | Comment)* ":)" /* ws: explicit */
/* gn: comments */
[257]    PITarget    ::=    [http://www.w3.org/TR/REC-xml#NT-PITarget]XML /* xgc: xml-version */
[258]    CharRef    ::=    [http://www.w3.org/TR/REC-xml#NT-CharRef]XML /* xgc: xml-version */
[259]    QName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names /* xgc: xml-version */
[260]    NCName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names /* xgc: xml-version */
[261]    S    ::=    [http://www.w3.org/TR/REC-xml#NT-S]XML /* xgc: xml-version */
[262]    Char    ::=    [http://www.w3.org/TR/REC-xml#NT-Char]XML /* xgc: xml-version */

The following symbols are used only in the definition of terminal symbols; they are not terminal symbols in the grammar of A.1 EBNF.

[263]    Digits    ::=    [0-9]+
[264]    CommentContents    ::=    (Char+ - (Char* ('(:' | ':)') Char*))

A.2.2 Terminal Delimitation

XQuery 4.0 expressions consist of terminal symbols and symbol separators.

Terminal symbols that are not used exclusively in /* ws: explicit */ productions are of two kinds: delimiting and non-delimiting.

[Definition: The delimiting terminal symbols are: S, "!", "!!", "!=", StringLiteral, "#", "#)", "$", "%", "(", "(#", ")", "*", "*:", "+", (comma), "-", "-->", "->", (dot), "..", "/", "//", "/>", (colon), ":*", "::", ":=", (semi-colon), "<", "<!--", "<![CDATA[", "</", "<<", "<=", "<?", "=", "=>", ">", ">=", ">>", "?", "?>", "??", "@", BracedURILiteral, "[", "]", "]]>", "]``", "``[", "`{", "{", "|", "||", "}", "}`" ]

[Definition: The non-delimiting terminal symbols are: IntegerLiteral, URIQualifiedName, NCName, DecimalLiteral, DoubleLiteral, QName, "NaN", "allowing", "ancestor", "ancestor-or-self", "and", "array", "as", "ascending", "at", "attribute", "base-uri", "boundary-space", "by", "case", "cast", "castable", "catch", "child", "collation", "comment", "construction", "context", "copy-namespaces", "count", "decimal-format", "decimal-separator", "declare", "default", "descendant", "descendant-or-self", "descending", "digit", "div", "document", "document-node", "element", "else", "empty", "empty-sequence", "encoding", "end", "enum", "eq", "every", "except", "exponent-separator", "external", "following", "following-sibling", "for", "function", "ge", "greatest", "group", "grouping-separator", "gt", "idiv", "if", "import", "in", "infinity", "inherit", "instance", "intersect", "is", "item", "item-type", "lax", "le", "least", "let", "lt", "map", "member", "minus-sign", "mod", "module", "namespace", "namespace-node", "ne", "next", "no-inherit", "no-preserve", "node", "of", "only", "option", "or", "order", "ordered", "ordering", "otherwise", "parent", "pattern-separator", "per-mille", "percent", "preceding", "preceding-sibling", "preserve", "previous", "processing-instruction", "record", "return", "satisfies", "schema", "schema-attribute", "schema-element", "self", "sliding", "some", "stable", "start", "strict", "strip", "switch", "text", "then", "to", "treat", "try", "tumbling", "type", "typeswitch", "union", "unordered", "validate", "variable", "version", "when", "where", "window", "with", "xquery", "zero-digit" ]

[Definition: Whitespace and Comments function as symbol separators. For the most part, they are not mentioned in the grammar, and may occur between any two terminal symbols mentioned in the grammar, except where that is forbidden by the /* ws: explicit */ annotation in the EBNF, or by the /* xgc: xml-version */ annotation.]

One or more symbol separators are required between two consecutive terminal symbols T and U (where T precedes U) when any of the following is true:

A.2.3 End-of-Line Handling

Prior to parsing, the XQuery 4.0 processor must normalize all line breaks. The rules for line breaking follow the rules of [XML 1.0] or [XML 1.1]. It is implementation-defined which version is used.

A.2.3.1 XML 1.0 End-of-Line Handling

For [XML 1.0] processing, all of the following must be translated to a single #xA character:

  1. the two-character sequence #xD #xA

  2. any #xD character that is not immediately followed by #xA.

A.2.3.2 XML 1.1 End-of-Line Handling

For [XML 1.1] processing, all of the following must be translated to a single #xA character:

  1. the two-character sequence #xD #xA

  2. the two-character sequence #xD #x85

  3. the single character #x85

  4. the single character #x2028

  5. any #xD character that is not immediately followed by #xA or #x85.

The characters #x85 and #x2028 cannot be reliably recognized and translated until the VersionDecl declaration (if present) has been read.

A.2.4 Whitespace Rules

A.2.4.1 Default Whitespace Handling

[Definition: A whitespace character is any of the characters defined by [http://www.w3.org/TR/REC-xml/#NT-S].]

[Definition: Ignorable whitespace consists of any whitespace characters that may occur between terminals, unless these characters occur in the context of a production marked with a ws:explicit annotation, in which case they can occur only where explicitly specified (see A.2.4.2 Explicit Whitespace Handling).] Ignorable whitespace characters are not significant to the semantics of an expression. Whitespace is allowed before the first terminal and after the last terminal of a module. Whitespace is allowed between any two terminals. Comments may also act as "whitespace" to prevent two adjacent terminals from being recognized as one. Some illustrative examples are as follows:

  • foo- foo results in a syntax error. "foo-" would be recognized as a QName.

  • foo -foo is syntactically equivalent to foo - foo, two QNames separated by a subtraction operator.

  • foo(: This is a comment :)- foo is syntactically equivalent to foo - foo. This is because the comment prevents the two adjacent terminals from being recognized as one.

  • foo-foo is syntactically equivalent to single QName. This is because "-" is a valid character in a QName. When used as an operator after the characters of a name, the "-" must be separated from the name, e.g. by using whitespace or parentheses.

  • 10div 3 results in a syntax error.

  • 10 div3 also results in a syntax error.

  • 10div3 also results in a syntax error.

A.2.4.2 Explicit Whitespace Handling

Explicit whitespace notation is specified with the EBNF productions, when it is different from the default rules, using the notation shown below. This notation is not inherited. In other words, if an EBNF rule is marked as /* ws: explicit */, the notation does not automatically apply to all the 'child' EBNF productions of that rule.

ws: explicit

/* ws: explicit */ means that the EBNF notation explicitly notates, with S or otherwise, where whitespace characters are allowed. In productions with the /* ws: explicit */ annotation, A.2.4.1 Default Whitespace Handling does not apply. Comments are not allowed in these productions except where the Comment non-terminal appears.

For example, whitespace is not freely allowed by the direct constructor productions, but is specified explicitly in the grammar, in order to be more consistent with XML.

A.3 Reserved Function Names

The following names are not allowed as function names in an unprefixed form because expression syntax takes precedence.

A.4 Precedence Order (Non-Normative)

The grammar in A.1 EBNF normatively defines built-in precedence among the operators of XQuery. These operators are summarized here to make clear the order of their precedence from lowest to highest. The associativity column indicates the order in which operators of equal precedence in an expression are applied.

# Operator Associativity
1 , (comma) either
2 FLWOR, some, every, switch, typeswitch, try, if NA
3 or either
4 and either
5 eq, ne, lt, le, gt, ge, =, !=, <, <=, >, >=, is, <<, >> NA
6 || left-to-right
7 to NA
8 +, - (binary) left-to-right
9 *, div, idiv, mod left-to-right
10 union, | either
11 intersect, except left-to-right
12 instance of NA
13 treat as NA
14 castable as NA
15 cast as NA
16 => left-to-right
17 -, + (unary) right-to-left
18 ! left-to-right
19 /, // left-to-right
20 [ ], ? left-to-right
21 ? (unary) NA

In the "Associativity" column, "either" indicates that all the operators at that level have the associative property (i.e., (A op B) op C is equivalent to A op (B op C)), so their associativity is inconsequential. "NA" (not applicable) indicates that the EBNF does not allow an expression that directly contains multiple operators from that precedence level, so the question of their associativity does not arise.

Note:

Parentheses can be used to override the operator precedence in the usual way. Square brackets in an expression such as A[B] serve two roles: they act as an operator causing B to be evaluated once for each item in the value of A, and they act as parentheses enclosing the expression B.

Curly braces in an expression such as validate{E} or ordered{E} perform a similar bracketing role to the parentheses in a function call, but with the difference in most cases that E is an Expr rather than ExprSingle, meaning that it can use the comma operator.