These rules mainly use familiar notations: «* » for repetition, parentheses for grouping, «? » to indicate that the preceding construct is optional, and « » to separate alternatives.
Simple tokens are represented using chevrons, for example «, » in the first rule represents a literal comma.
Sometimes multiple tokens are grouped inside a pair of chevrons, for example «for $ » in the third rule. This notation indicates that there are two tokens (whitespace may appear between them) but that the parser needs to recognize both tokens together in order to proceed. The keyword «for » on its own is not enough to recognize a ForExpr, because it might equally well be an element name appearing as a step in a path expression: the parser is therefore looking for the composite symbol consisting of the token «for » followed by the token «$ ».
Whitespace is always allowed between two tokens, whether these are grouped using chevrons or not. Whitespace is generally required between two tokens in cases where the first character of the second token could otherwise be taken as a continuation of the first token: for example, in the expression «$a - $b » whitespace is required before the «- » (but not after it). There are some exceptions to this rule: for example, whitespace is not required (but is allowed) before the «:: » that follows an axis name.
The rules as I have given them here do not correspond exactly with the rules as given in the W3C XPath specification. I have divided some rules and merged others for clarity, to correspond with the way the semantics are presented in XPath 2.0 Programmer's Reference. The W3C rules are sometimes distorted by the need to achieve a grammar that is provably nonambiguous, and also by the need to reuse syntactic elements between the XPath and XQuery specifications. I don't have these constraints here, so I can make it more user -friendly.
Symbol | Syntax |
---|---|
Expr | ExprSingle (, ExprSingle) * |
ExprSingle | ForExpr QuantifiedExpr If Expr OrExpr |
ForExpr | for $ VarName in ExprSingle (, $ VarName in ExprSingle)* return ExprSingle |
QuantifiedExpr | (some $ every $) VarName in ExprSingle (, $ VarName in ExprSingle)* satisfies ExprSingle |
If Expr | if (Expr) then ExprSingle else ExprSingle |
OrExpr | AndExpr (or AndExpr)* |
AndExpr | ComparisonExpr (and ComparisonExpr)* |
ComparisonExpr | RangeExpr (ValueComp GeneralComp NodeComp) RangeExpr)? |
ValueComp | eq ne lt le gt ge |
GeneralComp | = != < <= > >= |
NodeComp | is << >> |
RangeExpr | AdditiveExpr (to AdditiveExpr)? |
AdditiveExpr | MultiplicativeExpr ((+)-) MultiplicativeExpr)* |
MultiplicativeExpr | UnionExpr ((* div idiv mod) UnionExpr)* |
UnionExpr | IntersectExceptExpr ((union ) IntersectExceptExpr)* |
IntersectExceptExpr | InstanceOfExpr ((intersect except) InstanceOfExpr)* |
InstanceofExpr | TreatExpr (instance of SequenceType)? |
TreatExpr | CastableExpr (treat as SequenceType)? |
CastableExpr | CastExpr (castable as SingleType)? |
CastExpr | UnaryExpr (cast as SingleType)? |
UnaryExpr | (+-)* PathExpr |
PathExpr | (/ RelativePathExpr?) (// RelativePathExpr) RelativePathExpr |
RelativePathExpr | StepExpr ((/ //) StepExpr)* |
StepExpr | AxisStep FilterExpr |
AxisStep | (ForwardStep ReverseStep) PredicateList |
FilterExpr | PrimaryExpr PredicateList |
PredicateList | Predicate * |
Predicate | [ Expr ] |
PrimaryExpr | Literal VarRef ParenthesizedExpr ContextItemExpr FunctionCall |
Literal | NumericLiteral StringLiteral |
NumericLiteral | IntegerLiteral DecimalLiteral DoubleLiteral |
VarRef | $ VarName |
Parenthesized Expr | (Expr?) |
ContextItemExpr | . |
FunctionCall | FunctionName ((ExprSingle (, ExprSingle)*)?) |
FunctionName | QName |
ForwardStep | (ForwardAxis NodeTest) AbbrevForwardStep |
ReverseStep | (ReverseAxis NodeTest) AbbrevReverseStep |
Abbrev ForwardStep | @? NodeTest |
Abbrev ReverseStep | .. |
ForwardAxis | child:: descendant :: attribute:: self :: descendant-or-self :: following-sibling :: following :: namespace :: |
ReverseAxis | parent :: ancestor :: preceding-sibling :: preceding :: ancestor-or-self :: |
NodeTest | KindTest NameTest |
NameTest | QName Wildcard |
SingleType | AtomicType ?? |
SequenceType | (ItemType OccurrenceIndicator?) empty () |
AtomicType | QName |
ItemType | AtomicType KindTest item () |
Occurrence Indicator | ? * + |
KindTest | DocumentTest ElementTest AttributeTest PITest CommentTest TextTest AnyKindTest |
ElementTest | BasicElementTest SchemaElementTest |
AttributeTest | BasicAttributeTest SchemaAttributeTest |
Basic ElementTest | element ((ElementNameOrWildCard (, TypeName ??)?)?) |
Basic AttributeTest | attribute ((AttributeNameOrWildcard (, TypeName)?)?) |
ElementName OrWildcard | ElementName * |
AttributeName OrWildcard | AttributeName * |
ElementName | QName |
AttributeName | QName |
TypeName | QName |
Schema ElementTest | schema-element (ElementName) |
Schema AttributeTest | schema-attribute (AttributeName) |
PITest | processing-instruction ((NCName StringLiteral) ?) |
DocumentTest | document-node (ElementTest?) |
CommentTest | comment () |
TextTest | text () |
AnyKindTest | node () |