--- /dev/null
+grammar xpath;
+
+/*
+XPath 1.0 grammar. Should conform to the official spec at
+http://www.w3.org/TR/1999/REC-xpath-19991116. The grammar
+rules have been kept as close as possible to those in the
+spec, but some adjustmewnts were unavoidable. These were
+mainly removing left recursion (spec seems to be based on
+LR), and to deal with the double nature of the '*' token
+(node wildcard and multiplication operator). See also
+section 3.7 in the spec. These rule changes should make
+no difference to the strings accepted by the grammar.
+
+Written by Jan-Willem van den Broek
+Version 1.0
+
+Do with this code as you will.
+*/
+/*
+ Ported to Antlr4 by Tom Everett <tom@khubla.com>
+*/
+
+
+main : expr
+ ;
+
+locationPath
+ : relativeLocationPath
+ | absoluteLocationPathNoroot
+ ;
+
+absoluteLocationPathNoroot
+ : '/' relativeLocationPath
+ | '//' relativeLocationPath
+ ;
+
+relativeLocationPath
+ : step (('/'|'//') step)*
+ ;
+
+step : axisSpecifier nodeTest predicate*
+ | abbreviatedStep
+ ;
+
+axisSpecifier
+ : AxisName '::'
+ | '@'?
+ ;
+
+nodeTest: nameTest
+ | NodeType '(' ')'
+ | 'processing-instruction' '(' Literal ')'
+ ;
+
+predicate
+ : '[' expr ']'
+ ;
+
+abbreviatedStep
+ : '.'
+ | '..'
+ ;
+
+expr : orExpr
+ ;
+
+primaryExpr
+ : variableReference
+ | '(' expr ')'
+ | Literal
+ | Number
+ | functionCall
+ ;
+
+functionCall
+ : functionName '(' ( expr ( ',' expr )* )? ')'
+ ;
+
+unionExprNoRoot
+ : pathExprNoRoot ('|' unionExprNoRoot)?
+ | '/' '|' unionExprNoRoot
+ ;
+
+pathExprNoRoot
+ : locationPath
+ | filterExpr (('/'|'//') relativeLocationPath)?
+ ;
+
+filterExpr
+ : primaryExpr predicate*
+ ;
+
+orExpr : andExpr ('or' andExpr)*
+ ;
+
+andExpr : equalityExpr ('and' equalityExpr)*
+ ;
+
+equalityExpr
+ : relationalExpr (('='|'!=') relationalExpr)*
+ ;
+
+relationalExpr
+ : additiveExpr (('<'|'>'|'<='|'>=') additiveExpr)*
+ ;
+
+additiveExpr
+ : multiplicativeExpr (('+'|'-') multiplicativeExpr)*
+ ;
+
+multiplicativeExpr
+ : unaryExprNoRoot (('*'|'div'|'mod') multiplicativeExpr)?
+ | '/' (('div'|'mod') multiplicativeExpr)?
+ ;
+
+unaryExprNoRoot
+ : '-'* unionExprNoRoot
+ ;
+
+qName : nCName (':' nCName)?
+ ;
+
+// Does not match NodeType, as per spec.
+functionName
+ : nCName ':' nCName
+ | NCName
+ | AxisName
+ ;
+
+variableReference
+ : '$' qName
+ ;
+
+nameTest: '*'
+ | nCName ':' '*'
+ | qName
+ ;
+
+nCName : NCName
+ | AxisName
+ | NodeType
+ ;
+
+NodeType: 'comment'
+ | 'text'
+ | 'processing-instruction'
+ | 'node'
+ ;
+
+Number : Digits ('.' Digits?)?
+ | '.' Digits
+ ;
+
+fragment
+Digits : ('0'..'9')+
+ ;
+
+AxisName: 'ancestor'
+ | 'ancestor-or-self'
+ | 'attribute'
+ | 'child'
+ | 'descendant'
+ | 'descendant-or-self'
+ | 'following'
+ | 'following-sibling'
+ | 'namespace'
+ | 'parent'
+ | 'preceding'
+ | 'preceding-sibling'
+ | 'self'
+ ;
+
+
+ PATHSEP
+ :'/';
+ ABRPATH
+ : '//';
+ LPAR
+ : '(';
+ RPAR
+ : ')';
+ LBRAC
+ : '[';
+ RBRAC
+ : ']';
+ MINUS
+ : '-';
+ PLUS
+ : '+';
+ DOT
+ : '.';
+ MUL
+ : '*';
+ DOTDOT
+ : '..';
+ AT
+ : '@';
+ COMMA
+ : ',';
+ PIPE
+ : '|';
+ LESS
+ : '<';
+ MORE_
+ : '>';
+ LE
+ : '<=';
+ GE
+ : '>=';
+ COLON
+ : ':';
+ CC
+ : '::';
+ APOS
+ : '\'';
+ QUOT
+ : '"';
+
+Literal : '"' ~'"'* '"'
+ | '\'' ~'\''* '\''
+ ;
+
+Whitespace
+ : (' '|'\t'|'\n'|'\r')+ ->skip
+ ;
+
+NCName : NCNameStartChar NCNameChar*
+ ;
+
+fragment
+NCNameStartChar
+ : 'A'..'Z'
+ | '_'
+ | 'a'..'z'
+ | '\u00C0'..'\u00D6'
+ | '\u00D8'..'\u00F6'
+ | '\u00F8'..'\u02FF'
+ | '\u0370'..'\u037D'
+ | '\u037F'..'\u1FFF'
+ | '\u200C'..'\u200D'
+ | '\u2070'..'\u218F'
+ | '\u2C00'..'\u2FEF'
+ | '\u3001'..'\uD7FF'
+ | '\uF900'..'\uFDCF'
+ | '\uFDF0'..'\uFFFD'
+// Unfortunately, java escapes can't handle this conveniently,
+// as they're limited to 4 hex digits. TODO.
+// | '\U010000'..'\U0EFFFF'
+ ;
+
+fragment
+NCNameChar
+ : NCNameStartChar | '-' | '.' | '0'..'9'
+ | '\u00B7' | '\u0300'..'\u036F'
+ | '\u203F'..'\u2040'
+ ;
+
+