Skip to content

Instantly share code, notes, and snippets.

@eerohele
Last active September 11, 2018 21:22
Show Gist options
  • Save eerohele/c4040bbacd66c358c043 to your computer and use it in GitHub Desktop.
Save eerohele/c4040bbacd66c358c043 to your computer and use it in GitHub Desktop.
XPath 3.0 EBNF grammar (Instaparse-compatible except for instaparse/#114)
XPath ::= Expr
ParamList ::= Param ("," Param)*
Param ::= "$" EQName TypeDeclaration?
FunctionBody ::= EnclosedExpr
EnclosedExpr ::= "{" Expr "}"
Expr ::= ExprSingle ("," ExprSingle)*
ExprSingle ::= ForExpr
| LetExpr
| QuantifiedExpr
| IfExpr
| OrExpr
ForExpr ::= SimpleForClause "return" ExprSingle
SimpleForClause ::= "for" SimpleForBinding ("," SimpleForBinding)*
SimpleForBinding ::= "$" VarName "in" ExprSingle
LetExpr ::= SimpleLetClause "return" ExprSingle
SimpleLetClause ::= "let" SimpleLetBinding ("," SimpleLetBinding)*
SimpleLetBinding ::= "$" VarName ":=" ExprSingle
QuantifiedExpr ::= ("some" | "every") "$" VarName "in" ExprSingle ("," "$" VarName "in" ExprSingle)* "satisfies" ExprSingle
IfExpr ::= "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
OrExpr ::= AndExpr ( "or" AndExpr )*
AndExpr ::= ComparisonExpr ( "and" ComparisonExpr )*
ComparisonExpr ::= StringConcatExpr ( (ValueComp
| GeneralComp
| NodeComp) StringConcatExpr )?
StringConcatExpr ::= RangeExpr ( "||" RangeExpr )*
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 ::= ("-" | "+")* ValueExpr
ValueExpr ::= SimpleMapExpr
GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">="
ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge"
NodeComp ::= "is" | "<<" | ">>"
SimpleMapExpr ::= PathExpr ("!" PathExpr)*
PathExpr ::= ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
RelativePathExpr ::= StepExpr (("/" | "//") StepExpr)*
StepExpr ::= PostfixExpr | AxisStep
AxisStep ::= (ReverseStep | ForwardStep) PredicateList
ForwardStep ::= (ForwardAxis NodeTest) | AbbrevForwardStep
ForwardAxis ::= ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
| ("namespace" "::")
AbbrevForwardStep ::= "@"? NodeTest
ReverseStep ::= (ReverseAxis NodeTest) | AbbrevReverseStep
ReverseAxis ::= ("parent" "::")
| ("ancestor" "::")
| ("preceding-sibling" "::")
| ("preceding" "::")
| ("ancestor-or-self" "::")
AbbrevReverseStep ::= ".."
NodeTest ::= KindTest | NameTest
NameTest ::= EQName | Wildcard
Wildcard ::= "*"
| (NCName ":" "*")
| ("*" ":" NCName)
| (BracedURILiteral "*")
PostfixExpr ::= PrimaryExpr (Predicate | ArgumentList)*
ArgumentList ::= "(" (Argument ("," Argument)*)? ")"
PredicateList ::= Predicate*
Predicate ::= "[" Expr "]"
PrimaryExpr ::= Literal
| VarRef
| ParenthesizedExpr
| ContextItemExpr
| FunctionCall
| FunctionItemExpr
Literal ::= NumericLiteral | StringLiteral
NumericLiteral ::= IntegerLiteral | DecimalLiteral | DoubleLiteral
VarRef ::= "$" VarName
VarName ::= EQName
ParenthesizedExpr ::= "(" Expr? ")"
ContextItemExpr ::= "."
FunctionCall ::= EQName ArgumentList
Argument ::= ExprSingle | ArgumentPlaceholder
ArgumentPlaceholder ::= "?"
FunctionItemExpr ::= NamedFunctionRef | InlineFunctionExpr
NamedFunctionRef ::= EQName "#" IntegerLiteral
InlineFunctionExpr ::= "function" "(" ParamList? ")" ("as" SequenceType)? FunctionBody
SingleType ::= SimpleTypeName "?"?
TypeDeclaration ::= "as" SequenceType
SequenceType ::= ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
OccurrenceIndicator ::= "?" | "*" | "+"
ItemType ::= KindTest
| ("item" "(" ")")
| FunctionTest
| AtomicOrUnionType
| ParenthesizedItemType
AtomicOrUnionType ::= EQName
KindTest ::= DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| NamespaceNodeTest
| AnyKindTest
AnyKindTest ::= "node" "(" ")"
DocumentTest ::= "document-node" "(" (ElementTest | SchemaElementTest)? ")"
TextTest ::= "text" "(" ")"
CommentTest ::= "comment" "(" ")"
NamespaceNodeTest ::= "namespace-node" "(" ")"
PITest ::= "processing-instruction" "(" (NCName | StringLiteral)? ")"
AttributeTest ::= "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
AttribNameOrWildcard ::= AttributeName | "*"
SchemaAttributeTest ::= "schema-attribute" "(" AttributeDeclaration ")"
AttributeDeclaration ::= AttributeName
ElementTest ::= "element" "(" (ElementNameOrWildcard ("," TypeName "?"?)?)? ")"
ElementNameOrWildcard ::= ElementName | "*"
SchemaElementTest ::= "schema-element" "(" ElementDeclaration ")"
ElementDeclaration ::= ElementName
AttributeName ::= EQName
ElementName ::= EQName
SimpleTypeName ::= TypeName
TypeName ::= EQName
FunctionTest ::= AnyFunctionTest | TypedFunctionTest
AnyFunctionTest ::= "function" "(" "*" ")"
TypedFunctionTest ::= "function" "(" (SequenceType ("," SequenceType)*)? ")" "as" SequenceType
ParenthesizedItemType ::= "(" ItemType ")"
EQName ::= QName | URIQualifiedName
IntegerLiteral ::= Digits
DecimalLiteral ::= ("." Digits) | (Digits "." #'[0-9]*')
DoubleLiteral ::= (("." Digits) | (Digits ("." #'[0-9]*')?)) #'[eE]' #'[+-]'? Digits
StringLiteral ::= ('"' (EscapeQuot | #'[^\"]')* '"') | ("\'" (EscapeApos | #'[^\']')* "\'")
URIQualifiedName ::= BracedURILiteral NCName
BracedURILiteral ::= "Q" "{" #'[^{}]*' "}"
EscapeQuot ::= "\"\""
EscapeApos ::= "\'\'"
Comment ::= "(:" (CommentContents | Comment)* ":)"
QName ::= PrefixedName
| UnprefixedName
PrefixedName ::= Prefix ':' LocalPart
UnprefixedName ::= LocalPart
Prefix ::= NCName
LocalPart ::= NCName
NSAttName ::= PrefixedAttName | DefaultAttName
PrefixedAttName ::= 'xmlns:' NCName
DefaultAttName ::= 'xmlns'
NameStartChar ::= ":"
| #"[A-Z]"
| "_"
| #"[a-z]"
| #"[\\uC0-\\uD6]"
| #"[\\uD8-\\uF6]"
| #"[\\uF8-\\u2FF]"
| #"[\\u370-\\u37D]"
| #"[\\u37F-\\u1FFF]"
| #"[\\u200C-\\u200D]"
| #"[\\u2070-\\u218F]"
| #"[\\u2C00-\\u2FEF]"
| #"[\\u3001-\\uD7FF]"
| #"[\\uF900-\\uFDCF]"
| #"[\\uFDF0-\\uFFFD]"
| #"[\\u10000-\\uEFFFF]"
NameChar ::= NameStartChar
| "-"
| "."
| #"[0-9]"
| #"\\uB7"
| #"[\\u0300-\\u036F]"
| #"[\\u203F-\\u2040]"
Name ::= NameStartChar (NameChar)*
NCName ::= (!(Char* ':' Char*)) Name
Char ::= #"\\u9"
| #"\\uA"
| #"\\uD"
| #"[\\u20-\\uD7FF]"
| #"[\\uE000-\\uFFFD]"
| #"[\\u10000-\\u10FFFF]"
Digits ::= #'[0-9]+'
CommentContents ::= !(Char* ('(:' | ':)') Char*) Char+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment