grammar Test; options{ backtrack=true; } var : PATHTERM; PATHTERM: (PERCENT VARNAME PATHEXP); PERCENT: '$'; VARNAME: ((ALPHA) (ALPHA|DIGIT)*); fragment ALPHA: ('a'..'z' | 'A'..'Z'); fragment DIGIT: ('0'..'9'); xPath: PATHEXP; PATHEXP: ('/' RelativePathExpr?) | ('//' RelativePathExpr) | RelativePathExpr; fragment RelativePathExpr: primaryStep = StepExpr (( '/' | '//' ) trailingStep = StepExpr )*; fragment StepExpr: ( '.' | AbbrevForwardStep) (Predicate)?; fragment AbbrevForwardStep: attributeFlag = '@'? (stQName = QName | stNodeExpansion = '*') ; fragment Predicate: '[' PredicateExpr ']'; fragment PredicateExpr: Expr (('and'|'or') Expr)* | '(' Expr ')'; fragment Expr: PATHEXP (Comparisonexpr | Containmentexpr); fragment Comparisonexpr : (COMPARISONOP ) Literal; fragment Containmentexpr : ('contains' | 'excludes') '(' STRINGLITERAL ')'; fragment Literal : STRINGLITERAL | NumericLiteral | VarRef; fragment NumericLiteral: INTEGERLITERAL | DECIMALLITERAL | DOUBLELITERAL; fragment QName: (NCName ':' NCName) | NCName; // ---------------- Lexer Rules ---------------- // fragment LETTER: '\u0024' | '\u005f'|'\u0041'..'\u005a' | '\u0061'..'\u007a' | '\u00c0'..'\u00d6' | '\u00d8'..'\u00f6' | '\u00f8'..'\u00ff' | '\u0100'..'\u1fff' | '\u3040'..'\u318f' | '\u3300'..'\u337f' | '\u3400'..'\u3d2d' | '\u4e00'..'\u9fff' | '\uf900'..'\ufaff'; fragment INTEGERLITERAL : ('-')?('0'..'9')+; fragment DECIMALLITERAL : ('-')?('.' ('0'..'9')+) | (('0'..'9')+ '.' '0'..'9'*); fragment DOUBLELITERAL : ('-')?(('.' ('0'..'9')+) | (('0'..'9')+ ('.' '0'..'9'*)?)) ('e' | 'E') ('+' | '-')? ('0'..'9')+; fragment STRINGLITERAL : ('"' ~('"')* '"') | ('\'' ~('\'')* '\''); fragment COMPARISONOP : ('=' | '<' | '>' | '<>' | '!=' | '<=' | '>='); fragment VarRef: '$' NCName; fragment NCName : (LETTER) (LETTER | ('0'..'9') | '.' | '-')*; WS : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ {$channel=HIDDEN;}; SL_COMMENT: '--' (~('\n'|'\r'))* ('\n'|'\r'('\n')?) {$channel=HIDDEN;}; ML_COMMENT: '/**' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;};