## 1 XQuery Grammar

### 1.1 Lexical structure

A character is an atomic unit of text as specified by ISO/IEC 10646 [ISO10646] (see also [ISO10646-2000]). Legal characters are tab, carriage return, line feed, and the legal characters of Unicode and ISO/IEC 10646, as long as these characters are legal XML characters as defined in the [XML] recommendation.

A lexical pattern is a rule that describes how a sequence of characters can match a grammar unit. A lexeme is the smallest meaningful unit in the grammar that has syntactic interpretation. A token is a symbol that matches lexemes, and is the output of the lexical analyzer. A token symbol is the symbolic name given to that token. A single token may be composed of one or more lexemes. If there is more than one lexeme, they may be separated by whitespace or punctuation. For instance, the token AxisDescendantOrSelf has two lexemes, "descendant-or-self" and "::".

Pattern | Lexeme(s) | Token Names (for example)
--- | --- | ---
"or" | "or" | Or
"=" | "=" | Equals
(Prefix ':')? LocalPart | "p:foo" | QName
<"descendant-or-self" "::"> | "descendant-or-self" | AxisDescendantOrSelf
"::"

When patterns are simple string matches, the strings are embedded directly into the BNF. In other cases, token symbols are used when the pattern is a more complex regular expression (the major cases of these are NCName, QName, and Number and String literals). It is up to an implementation to decide on the exact tokenization strategy, which may be different depending on the parser construction. For instance, an implementation may decide that a token named `For` is composed of only "for", or may decide that it is composed of ("for" "("). In the first case the implementation may decide to use lexical lookahead to distinguish the "for" lexeme from a QName that has the lexeme "for". In the second case, the implementation may decide to combine the two lexemes into a single "long" token. In either case, the end grammatical result will be the same. Lexemes that must be described by lexical lookahead are delimited with the tokens that it must look ahead to, in order to be recoginized, by "<" and ">".

This grammar implies lexical states, which are lexical constraints on the tokenization process based on grammatical positioning. The exact structure of these states is left to the implementation, but the normative rules for calculating these states are given in the 1.1.2 Lexical Rules section.

When tokenizing, the longest possible match that is valid in the current lexical state is prefered .

For readability, Whitespace may be used in most expressions even though not explicitly allowed by the grammar: Whitespace may be freely added between lexemes, except a few cases where whitespace is needed to disambiguate the token. For instance, in XML, "-" is a valid character in an element or attribute name. When used as an operator after the characters of a name, it must be separated from the name, e.g. by using whitespace or parentheses.

For XMLQuery, Whitespace is not freely allowed in the Constructor productions, but is specified specifically in the grammar, in order to be more consistent with XML. Lexically, these states are as follows: START_TAG, ELEMENT_CONTENT, END_TAG, XML_COMMENT, PROCESSING_INSTRUCTION, CDATA_SECTION, QUOT_ATTRIBUTE_CONTENT, and APOS_ATTRIBUTE_CONTENT.

All keywords are case sensitive.

> Ed. Note: Since currently ExprComments are specified at the lexical level, I leave it as an editorial issue as to how to describe this, or whether to constrain where ExprComments are allowed so they can be described by the BNF. (I would be in favor of this. -sb)

#### 1.1.1 Syntactic Constructs

- Character Classes

  The following basic tokens are defined in [XML].

  1. Letter

  2. BaseChar

  3. Ideographic

  4. CombiningChar

  5. Digit

  6. Extender

- Identifiers

  The following identifier components are defined in [XMLNAMES].

  1. NCName

  2. NCNameChar

  3. QName

  4. Prefix

  5. LocalPart

- String Literals and Numbers

  [194] | `IntegerLiteral` | ::= | `Digits`
  [195] | `DecimalLiteral` | ::= | `("." Digits) | (Digits "." [0-9]*)`
  [196] | `DoubleLiteral` | ::= | `(("." Digits) | (Digits ("." [0-9]*)?)) ("e" | "E") ("+" | "-")? Digits`
  [215] | `StringLiteral` | ::= | `('"' (('"' '"') | [^"])* '"') | ("'" (("'" "'") | [^'])* "'")`

- Comments

  Comments are lexical constructs only, and do not affect the processing of an expression. [Ed. Note: Need to expand on where, exactly, comments are allowed.]

  [94] | `ExprComment` | ::= | `"{--" [^}]* "--}"`

- Defined Tokens

  The following is a list of defined tokens for the XQuery grammar.

  [95] | `S` | ::= | `WhitespaceChar+`
  [149] | `Nmstart` | ::= | `Letter | "_"`
  [150] | `Nmchar` | ::= | `Letter | CombiningChar | Extender | Digit | "." | "-" | "_"`
  [193] | `Digits` | ::= | `[0-9]+`
  [212] | `EscapeQuot` | ::= | `'"' '"'`
  [217] | `URLLiteral` | ::= | `('"' (('"' '"') | [^"])* '"') | ("'" (("'" "'") | [^'])* "'")`
  [226] | `PITarget` | ::= | `NCName`
  [228] | `VarName` | ::= | `QName`
  [229] | `FuncName` | ::= | `(Prefix ":")? LocalPart`
  [232] | `NCNameForPrefix` | ::= | `Nmstart Nmchar*`
  [235] | `PredefinedEntityRef` | ::= | `"&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"`
  [236] | `HexDigits` | ::= | `([0-9] | [a-f] | [A-F])+`
  [237] | `CharRef` | ::= | `"&#" (Digits | ("x" HexDigits)) ";"`
  [251] | `EscapeApos` | ::= | `"''"`
  [254] | `Char` | ::= | `([#x0009] | [#x000D] | [#x000A] | [#x0020-#xFFFD])`
  [255] | `WhitespaceChar` | ::= | `([#x0009] | [#x000D] | [#x000A] | [#x0020])`

#### 1.1.2 Lexical Rules

As discussed above, there are various strategies that can be used by an implementation to disambiguate token symbol choices. Among the choices are lexical look-ahead and look-behind, a two-pass lexical evaluation, and a single recursive descent lexical evaluation and parse. This specification does not dictate what strategy to use. However, this section does describe normative rules with which these decisions must conform to.

The lexical contexts and transitions between lexical contexts is described in terms of a series of states and transitions between those states. An implementation need not follow this approach in implementing lexer rules, but does need to conform to the results. For instance, instead of using a state automata, an implementation might use lexecal look-behind, or might use a full context-free-grammar parse, or it might make extensive use of parser lookahead (and use a more ambiguous token strategy).

The tables below define the complete lexical rules for XQuery. Each table corresponds to a lexical state in which the tokens listed are recognized only in that state. When a given token is recognized in the given state, the transition to the next state is given. In some cases, a transition will "push" the current state or a specific state onto an abstract stack, and will later restore that state by a "pop" when another lexical event occurs. [Ed. Note: `pushParenState(...)`, `popParenState(...)`, and `resetParenStateOrSwitch(...)` are left unexplained for now. Briefly, these are used to maintain the `ITEMTYPE` state within a function definition in XQuery, since it is hard to distinguish lexically between a function call and a function definition. Since the lexical state mechanism is shared between XPath and XQuery, these are used in the XPath tables also, even though they are not strictly needed.]

The lexical states have in many cases close connection to the parser productions. However, just because a token is recognized in a certain lexical state, does not mean it will be legal in the parser state.

#### The #ANY State

This state is for patterns that can be recognized in any state.

Pattern | Transition To State
--- | ---
WhitespaceChar Nmstart Nmchar Digits HexDigits | (maintain current state)

#### The DEFAULT State

This state is for patterns that occur at the beginning of an expression.

Pattern | Transition To State
--- | ---
"?" "[" "+" "-" ";" "empty" "stable" <"at" StringLiteral> | DEFAULT
"{" | DEFAULT pushState(DEFAULT)
<"attribute" QName "{"> <"element" QName "{"> <"element" "{"> <"document" "{"> <"attribute" "{"> | DEFAULT pushState(DEFAULT)
<"type" QName> "validate" "*" <NCName ":" "*"> <"*" ":" NCName> "." ".." StringLiteral | OPERATOR
<"of" "type"> "/" "//" <"child" "::"> <"descendant" "::"> <"parent" "::"> <"attribute" "::"> <"self" "::"> <"descendant-or-self" "::"> "@" | QNAME
<"default" "collation" "="> <"declare" "namespace"> | NAMESPACEDECL
<"default" "element"> <"default" "function"> <"import" "schema"> | NAMESPACEKEYWORD
<"declare" "xmlspace"> | XMLSPACE_DECL
"for" "let" "some" "every" <"cast" "as"> <"treat" "as"> | ITEMTYPE
<"define" "function"> | FUNCDEF
"$" | VARNAME
| START_TAG pushState(OPERATOR)
"<!--" | XML_COMMENT pushState()
"<?" | PROCESSING_INSTRUCTION pushState()
"<![CDATA[" | CDATA_SECTION pushState()
S | (maintain state)
"," | resetParenStateOrSwitch(DEFAULT)
"(" | pushParenState(DEFAULT)
<"text" "("> <"comment" "("> <"node" "("> <"processing-instruction" "("> | pushParenState(DEFAULT)
<QName "("> <"if" "("> | pushParenState(DEFAULT)
")" | popParenState(OPERATOR)
"unordered" | (maintain state)
<")" "returns"> | popParenState(ITEMTYPE)
"}" | popState

#### The OPERATOR State

This state is for patterns that are defined for operators.

Pattern | Transition To State
--- | ---
"/" "//" "div" "idiv" "mod" "and" "or" "*" "return" "then" "else" "to" "union" "intersect" "except" "=" "is" "!=" "isnot" "<=" ">=" "<" ">" "|" "<<" ">>" "eq" "ne" "gt" "ge" "lt" "le" "in" "where" "satisfies" ":=" "?" "[" "+" "-" ";" <"at" StringLiteral> "item" "node" "document" "comment" "text" | DEFAULT
"{" | DEFAULT pushState(DEFAULT)
<NCName ":" "*"> <"*" ":" NCName> "." ".." "ascending" "descending" <"empty" "greatest"> <"empty" "least"> StringLiteral "default" | OPERATOR
<"of" "type"> | QNAME
<"default" "collation" "="> <"declare" "namespace"> | NAMESPACEDECL
<"default" "element"> <"default" "function"> <"import" "schema"> | NAMESPACEKEYWORD
<"declare" "xmlspace"> | XMLSPACE_DECL
"for" "let" "some" "every" <"instance" "of"> "case" | ITEMTYPE
<"define" "function"> | FUNCDEF
"$" | VARNAME
S | (maintain state)
<"sort" "by" "("> | pushParenState(DEFAULT)
"," | resetParenStateOrSwitch(DEFAULT)
"(" | pushParenState(DEFAULT)
")" | popParenState(OPERATOR)
"unordered" | (maintain state)
<")" "returns"> | popParenState(ITEMTYPE)
"}" | popState

#### The QNAME State

When a qualified name is expected, and it is required to remove ambiguity from patterns that look like keywords, this state is used.

Pattern | Transition To State
--- | ---
";" | DEFAULT
"*" <NCName ":" "*"> <"*" ":" NCName> "." ".." | OPERATOR
"/" "//" <"child" "::"> <"descendant" "::"> <"parent" "::"> <"attribute" "::"> <"self" "::"> <"descendant-or-self" "::"> "@" | QNAME
"$" | VARNAME
S | (maintain state)
"(" | pushParenState(DEFAULT)
<"text" "("> <"comment" "("> <"node" "("> <"processing-instruction" "("> | pushParenState(DEFAULT)
")" | popParenState(OPERATOR)
<")" "returns"> | popParenState(ITEMTYPE)

#### The NAMESPACEDECL State

This state occurs inside of a namespace declaration, and is needed to recognize a NCName that is to be used as the prefix, as opposed to allowing a QName to occur. (Otherwise, the difference between NCName and QName are ambiguous.)

Pattern | Transition To State
--- | ---
URLLiteral | DEFAULT
"=" NCNameForPrefix | NAMESPACEDECL
S | (maintain state)

#### The NAMESPACEKEYWORD State

This state occurs at places where the keyword "namespace" is expected, which would otherwise be ambiguous compared to a QName. QNames can not occur in this state.

Pattern | Transition To State
--- | ---
StringLiteral | OPERATOR
"namespace" | NAMESPACEDECL
S | (maintain state)

#### The XMLSPACE_DECL State

This state occurs at places where the keywords "preserve" and "strip" is expected to support "declare xmlspace". QNames can not occur in this state.

Pattern | Transition To State
--- | ---
"preserve" "strip" | DEFAULT
"=" | (maintain state)

#### The ITEMTYPE State

This state distinguishes tokens that can occur only inside the ItemType production.

Pattern | Transition To State
--- | ---
"attribute" "element" "node" "document" "comment" "text" "processing-instruction" "item" "untyped" <"atomic" "value"> AtomicType | DEFAULT
<NCName ":" "*"> <"*" ":" NCName> "." ".." | OPERATOR
"$" | VARNAME
S | (maintain state)
")" | popParenState(OPERATOR)
<")" "returns"> | popParenState(ITEMTYPE)

#### The FUNCDEF State

This state is defined to recognise a FuncName, which then transitions to an ITEMTYPE state after the opening left bracket, in order to recognize SequenceType productions.

Pattern | Transition To State
--- | ---
S | (maintain state)
FuncName | (maintain state)
"(" | pushParenState(ITEMTYPE)

#### The VARNAME State

This state differentiates variable names from qualified names. This allows only the pattern of a QName to be recognized when otherwise ambiguities could occur.

Pattern | Transition To State
--- | ---
VarName | OPERATOR

#### The START_TAG State

This state allows attributes in the native XML syntax, and marks the beginning of an element construction. Element constructors also push the current state, popping it at the conclusion of an end tag. In the START_TAG state, the string ">" is recognized as a token which is associated with the transition to the original state.

Pattern | Transition To State
--- | ---
| DEFAULT pushState()
">" | ELEMENT_CONTENT
'"' | QUOT_ATTRIBUTE_CONTENT
"'" | APOS_ATTRIBUTE_CONTENT
S | (maintain state)
QName | (maintain state)
"=" | (maintain state)
"/>" | popState

#### The ELEMENT_CONTENT State

This state allows XML-like content, without these characters being misinterpreted as expressions. The character "{" marks a transition to the DEFAULT state, i.e. the start of an embedded expression, and the "}" character pops back to the ELEMENT_CONTENT state. To allow curly braces to be used as character content, a double left or right curly brace is interpreted as a single curly brace character. The string "</" is interpreted as the beginning of an end tag, which is associated with a transition to the END_TAG state.

Pattern | Transition To State
--- | ---
| DEFAULT pushState()
"<" | START_TAG pushState()
"</" | END_TAG
"<!--" | XML_COMMENT pushState()
"<?" | PROCESSING_INSTRUCTION pushState()
"<![CDATA[" | CDATA_SECTION pushState()
"]]>" | popState
PredefinedEntityRef CharRef | (maintain state)
"{{" "}}" | (maintain state)
Char | (maintain state)

#### The END_TAG State

When the end tag is terminated, the state is popped to the state that was pushed at the start of the corresponding start tag.

Pattern | Transition To State
--- | ---
| DEFAULT pushState()
S | (maintain state)
QName | (maintain state)
">" | popState

#### The XML_COMMENT State

The "<--" token marks the beginning of an XML Comment, and the "-->" token marks the end. This allows no special interpretation of other characters in this state.

Pattern | Transition To State
--- | ---
Char | (maintain state)
"-->" | popState

#### The PROCESSING_INSTRUCTION State

In this state, only lexemes that are legal in a processing instruction name are recognized.

Pattern | Transition To State
--- | ---
PITarget | PROCESSING_INSTRUCTION_CONTENT

#### The PROCESSING_INSTRUCTION_CONTENT State

In this state, only characters are that are legal in processing instruction content are recognized.

Pattern | Transition To State
--- | ---
Char | (maintain state)
"?>" | popState

#### The CDATA_SECTION State

In this state, only lexemes that are legal in a CDATA section are recognized.

Pattern | Transition To State
--- | ---
"]]>" | popState
Char | (maintain state)

#### The QUOT_ATTRIBUTE_CONTENT State

This state allows content legal for attributes. The character "{" marks a transition to the DEFAULT state, i.e. the start of an embedded expression, and the "}" character pops back to the original state. To allow curly braces to be used as character content, a double left or right curly brace is interpreted as a single curly brace character. This state is the same as QUOT_ATTRIBUTE_CONTENT, except that apostrophes are allowed without escaping, and an unescaped quote marks the end of the state.

Pattern | Transition To State
--- | ---
| DEFAULT pushState()
'"' | START_TAG
EscapeQuot | QUOT_ATTRIBUTE_CONTENT
PredefinedEntityRef CharRef | (maintain state)
"{{" "}}" | (maintain state)
Char | (maintain state)

#### The APOS_ATTRIBUTE_CONTENT State

This state is the same as QUOT_ATTRIBUTE_CONTENT, except that quotes are allowed, and an unescaped apostrophe marks the end of the state.

Pattern | Transition To State
--- | ---
| DEFAULT pushState()
"'" | START_TAG
EscapeApos | APOS_ATTRIBUTE_CONTENT
PredefinedEntityRef CharRef | (maintain state)
"{{" "}}" | (maintain state)
Char | (maintain state)

### 1.2 BNF

The following grammar uses the same Basic EBNF notation as [XML], except that grammar symbols always have initial capital letters. The EBNF contains the lexemes embedded in the productions.

Note:

Note that the Semicolon character is reserved for future use.

## NON-TERMINALS

[1] | `Query` | ::= | `QueryProlog QueryBody`
[2] | `QueryProlog` | ::= | `(NamespaceDecl | XMLSpaceDecl | DefaultNamespaceDecl | DefaultCollationDecl | SchemaImport)* FunctionDefn*`
[3] | `QueryBody` | ::= | `ExprSequence?`
[4] | `ExprSequence` | ::= | `Expr ("," Expr)*`
[5] | `Expr` | ::= | `SortExpr`
[6] | `SortExpr` | ::= | `OrExpr ( "stable"? <"sort" "by" "("> SortSpecList ")" )*`
[7] | `OrExpr` | ::= | `AndExpr ( "or" AndExpr )*`
[8] | `AndExpr` | ::= | `UnorderedExpr ( "and" UnorderedExpr )*`
[9] | `UnorderedExpr` | ::= | `"unordered"? FLWRExpr`
[10] | `FLWRExpr` | ::= | `((ForClause | LetClause)+ WhereClause? "return")* QuantifiedExpr`
[11] | `QuantifiedExpr` | ::= | `(("some" | "every") TypeDeclaration? "$" VarName "in" Expr ("," TypeDeclaration? "$" VarName "in" Expr)* "satisfies")* TypeswitchExpr`
[12] | `TypeswitchExpr` | ::= | `(<"typeswitch" "("> Expr ")" CaseClause+ "default" ("$" VarName)? "return")* IfExpr`
[13] | `IfExpr` | ::= | `(<"if" "("> Expr ")" "then" Expr "else")* InstanceofExpr`
[14] | `InstanceofExpr` | ::= | `ComparisonExpr ( <"instance" "of"> SequenceType )?`
[15] | `ComparisonExpr` | ::= | `RangeExpr ( (ValueComp | GeneralComp | NodeComp | OrderComp) RangeExpr )?`
[16] | `RangeExpr` | ::= | `AdditiveExpr ( "to" AdditiveExpr )*`
[17] | `AdditiveExpr` | ::= | `MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*`
[18] | `MultiplicativeExpr` | ::= | `UnionExpr ( ("*" | "div" | "idiv" | "mod") UnionExpr )*`
[19] | `UnionExpr` | ::= | `IntersectExceptExpr ( ("union" | "|") IntersectExceptExpr )*`
[20] | `IntersectExceptExpr` | ::= | `UnaryExpr ( ("intersect" | "except") UnaryExpr )*`
[21] | `UnaryExpr` | ::= | `("-" | "+")* ValueExpr`
[22] | `ValueExpr` | ::= | `ValidateExpr | CastExpr | Constructor | PathExpr`
[23] | `PathExpr` | ::= | `("/" RelativePathExpr?) | ("//" RelativePathExpr) | RelativePathExpr`
[24] | `RelativePathExpr` | ::= | `StepExpr (("/" | "//") StepExpr)*`
[25] | `StepExpr` | ::= | `(ForwardStep | ReverseStep | PrimaryExpr) Predicates`
[26] | `ForClause` | ::= | `"for" TypeDeclaration? "$" VarName "in" Expr ("," TypeDeclaration? "$" VarName "in" Expr)*`
[27] | `LetClause` | ::= | `"let" TypeDeclaration? "$" VarName ":=" Expr ("," TypeDeclaration? "$" VarName ":=" Expr)*`
[28] | `WhereClause` | ::= | `"where" Expr`
[29] | `ValidateExpr` | ::= | `"validate" SchemaContext? "{" Expr "}"`
[30] | `CastExpr` | ::= | `(<"cast" "as"> | <"treat" "as">) SequenceType ParenthesizedExpr`
[31] | `Constructor` | ::= | `ElementConstructor | XmlComment | XmlProcessingInstruction | CdataSection | ComputedDocumentConstructor | ComputedElementConstructor | ComputedAttributeConstructor`
[32] | `GeneralComp` | ::= | `"=" | "!=" | "<" | "<=" | ">" | ">="`
[33] | `ValueComp` | ::= | `"eq" | "ne" | "lt" | "le" | "gt" | "ge"`
[34] | `NodeComp` | ::= | `"is" | "isnot"`
[35] | `OrderComp` | ::= | `"<<" | ">>"`
[36] | `SortSpecList` | ::= | `Expr SortModifier ("," SortSpecList)?`
[37] | `SortModifier` | ::= | `("ascending" | "descending")? (<"empty" "greatest"> | <"empty" "least">)?`
[38] | `CaseClause` | ::= | `"case" SequenceType ("$" VarName)? "return" Expr`
[39] | `PrimaryExpr` | ::= | `Literal | FunctionCall | ("$" VarName) | ParenthesizedExpr`
[40] | `ForwardAxis` | ::= | `<"child" "::"> | <"descendant" "::"> | <"attribute" "::"> | <"self" "::"> | <"descendant-or-self" "::">`
[41] | `ReverseAxis` | ::= | `<"parent" "::">`
[42] | `NodeTest` | ::= | `KindTest | NameTest`
[43] | `NameTest` | ::= | `QName | Wildcard`
[44] | `Wildcard` | ::= | `"*" | <NCName ":" "*"> | <"*" ":" NCName>`
[45] | `KindTest` | ::= | `ProcessingInstructionTest | CommentTest | TextTest | AnyKindTest`
[46] | `ProcessingInstructionTest` | ::= | `<"processing-instruction" "("> StringLiteral? ")"`
[47] | `CommentTest` | ::= | `<"comment" "("> ")"`
[48] | `TextTest` | ::= | `<"text" "("> ")"`
[49] | `AnyKindTest` | ::= | `<"node" "("> ")"`
[50] | `ForwardStep` | ::= | `(ForwardAxis NodeTest) | AbbreviatedForwardStep`
[51] | `ReverseStep` | ::= | `(ReverseAxis NodeTest) | AbbreviatedReverseStep`
[52] | `AbbreviatedForwardStep` | ::= | `"." | ("@" NameTest) | NodeTest`
[53] | `AbbreviatedReverseStep` | ::= | `".."`
[54] | `Predicates` | ::= | `("[" Expr "]")*`
[55] | `NumericLiteral` | ::= | `IntegerLiteral | DecimalLiteral | DoubleLiteral`
[56] | `Literal` | ::= | `NumericLiteral | StringLiteral`
[57] | `ParenthesizedExpr` | ::= | `"(" ExprSequence? ")"`
[58] | `FunctionCall` | ::= | `<QName "("> (Expr ("," Expr)*)? ")"`
[59] | `Param` | ::= | `SequenceType? "$" VarName`
[60] | `SchemaContext` | ::= | `"in" SchemaGlobalContext ("/" SchemaContextStep)*`
[61] | `SchemaGlobalContext` | ::= | `QName | <"type" QName>`
[62] | `SchemaContextStep` | ::= | `QName`
[63] | `TypeDeclaration` | ::= | `SequenceType`
[64] | `SequenceType` | ::= | `(ItemType OccurrenceIndicator) | "empty"`
[65] | `ItemType` | ::= | `(("element" | "attribute") ElemOrAttrType?) | "node" | "processing-instruction" | "comment" | "text" | "document" | "item" | AtomicType | "untyped" | <"atomic" "value">`
[66] | `ElemOrAttrType` | ::= | `(QName (SchemaType | SchemaContext?)) | SchemaType`
[67] | `SchemaType` | ::= | `<"of" "type"> QName`
[68] | `AtomicType` | ::= | `QName`
[69] | `OccurrenceIndicator` | ::= | `("*" | "*" | "+" | "?")?`
[70] | `ElementConstructor` | ::= | `"<" QName AttributeList ("/>" | (">" ElementContent* "</" QName S? ">"))`
[71] | `ComputedDocumentConstructor` | ::= | `<"document" "{"> ExprSequence "}"`
[72] | `ComputedElementConstructor` | ::= | `(<"element" QName "{"> | (<"element" "{"> Expr "}" "{")) ExprSequence? "}"`
[73] | `ComputedAttributeConstructor` | ::= | `(<"attribute" QName "{"> | (<"attribute" "{"> Expr "}" "{")) ExprSequence? "}"`
[74] | `CdataSection` | ::= | `"<![CDATA[" Char* "]]>"`
[75] | `XmlProcessingInstruction` | ::= | `"<?" PITarget Char* "?>"`
[76] | `XmlComment` | ::= | `"<!--" Char* "-->"`
[77] | `ElementContent` | ::= | `Char | "{{" | "}}" | ElementConstructor | EnclosedExpr | CdataSection | CharRef | PredefinedEntityRef | XmlComment | XmlProcessingInstruction`
[78] | `AttributeList` | ::= | `(S (QName S? "=" S? AttributeValue)?)*`
[79] | `AttributeValue` | ::= | `('"' (EscapeQuot | AttributeValueContent)* '"') | ("'" (EscapeApos | AttributeValueContent)* "'")`
[80] | `AttributeValueContent` | ::= | `Char | CharRef | "{{" | "}}" | EnclosedExpr | PredefinedEntityRef`
[81] | `EnclosedExpr` | ::= | `"{" ExprSequence "}"`
[82] | `XMLSpaceDecl` | ::= | `<"declare" "xmlspace"> "=" ("preserve" | "strip")`
[83] | `DefaultCollationDecl` | ::= | `<"default" "collation" "="> URLLiteral`
[84] | `NamespaceDecl` | ::= | `<"declare" "namespace"> NCNameForPrefix "=" URLLiteral`
[85] | `SubNamespaceDecl` | ::= | `"namespace" NCNameForPrefix "=" URLLiteral`
[86] | `DefaultNamespaceDecl` | ::= | `(<"default" "element"> | <"default" "function">) "namespace" "=" URLLiteral`
[87] | `FunctionDefn` | ::= | `<"define" "function"> FuncName "(" ParamList? (")" | (<")" "returns"> SequenceType)) EnclosedExpr`
[88] | `ParamList` | ::= | `Param ("," Param)*`
[89] | `SchemaImport` | ::= | `<"import" "schema"> (StringLiteral | SubNamespaceDecl | DefaultNamespaceDecl) <"at" StringLiteral>?`

### 1.3 Reserved Words

The following is a list of reserved words for XQuery:

- `for`

- `let`

- `some`

- `every`

- `unordered`

- `validate`

> Ed. Note: This version of the grammar has made an attempt to reduce the number of reserved words.

> Ed. Note: See issue xpath-issue-reserved-words.

### 1.4 Precedence Order

In all cases the grammar defines built-in precedence. In the cases where a number of statements are a choice at the same production level, the expressions are always evaluated from left to right.