blob: 5f7ffc4ed8cb8aa50e94e0887ad08635b6cf4c0e [file] [log] [blame]
syntax XPath(k = 0) {
primitiveTemplate identifier for String default using NAME:
value = "%token%";
primitiveTemplate stringSymbol for String using STRING:
value = "%token%",
serializer="'\'' + %value%.toCString() + '\''";
primitiveTemplate integerSymbol for Integer default using INT:
value = "Integer.valueOf(%token%)";
primitiveTemplate floatSymbol for Double default using FLOAT:
value = "Double.valueOf(%token%)";
-- Expressions
template Expression main abstract operatored;
template VariableExp
: "$" name
;
template PathExpression
:
-- (isAbsolute ? "/")
-- steps{separator = "/"}
(isAbsolute ?
"/" steps{separator = "/"}
:
steps{separator = "/", forcedLower = 1}
)
;
template Step(disambiguate = "(step)=>")
:
[[ axis nodeTest
| "." -- {{axis <- new SelfAxis, nodeTest <- new IsNodeTest}} -- self::node()
| ".." -- {{axis <- new ParentAxis, nodeTest <- new IsNodeTest}} -- parent::node()
]]
predicates
;
template Predicate
: "[" expression "]"
;
operatorTemplate OperatorCallExp(operators =
opUnion
opMinus1
opMul opDiv opMod
opPlus opMinus
opLT
opLE
opGT
opGE
opEQ
opNE
opAnd
opOr,
source = 'left', storeOpTo = name, storeRightTo = 'right');
template FunctionCallExp(disambiguate = "NAME LPAREN")
: name "(" arguments{separator = ","} ")"
;
template LiteralExp abstract;
template IntegerExp
: symbol
;
template StringExp
: symbol{as = stringSymbol}
;
-- End Expressions
-- NodeTests
template NodeTest abstract;
template NameTest
: name
;
template WildCardTest
: "*"
;
template IsNodeTest
: "node" "(" ")"
;
template IsTextTest
: "text" "(" ")"
;
-- End NodeTests
-- Axes
template Axis abstract;
template AncestorAxis
: "ancestor" "::"
;
template AncestorOrSelfAxis
: "ancestor-or-self" "::"
;
template AttributeAxis
: [[ "attribute" "::"
| "@"
]]
;
template ChildAxis
: [[ "child" "::"
| -- *nothing* is equivalent to child::
]]
;
template DescendantAxis
: "descendant" "::"
;
template DescendantOrSelfAxis
: "descendant-or-self" "::"
;
template FollowingAxis
: "following" "::"
;
template FollowingSiblingAxis
: "following-sibling" "::"
;
template NamespaceAxis
: "namespace" "::"
;
template ParentAxis
: "parent" "::"
;
template PrecedingAxis
: "preceding" "::"
;
template PrecedingSiblingAxis
: "preceding-sibling" "::"
;
template SelfAxis
: "self" "::"
;
-- End Axes
symbols {
dollar = "$";
lsquare = "[";
rsquare = "]";
lparen = "(";
rparen = ")";
colons = "::";
point = ".";
pointpoint = "..";
arobas = "@";
slash = "/";
-- operator symbols
pipe = "|";
minus = "-";
star = "*";
slashslash = "//";
plus = "+";
eq = "=";
gt = ">";
lt = "<";
ge = ">=";
le = "<=";
excleq = "!=";
}
operators {
priority 0 {
-- opPredicate []
}
priority 1 {
-- opChild = slash, 2;
-- opDescendant = slashslash, 2;
}
priority 2 {
opUnion = pipe, 2;
}
priority 3 {
opMinus1 = minus, 1;
}
priority 4 {
opMul = star, 2;
opDiv = "div", 2;
opMod = "mod", 2;
}
priority 5 {
opPlus = plus, 2;
opMinus = minus, 2;
}
priority 6 {
opLT = lt, 2;
opLE = le, 2;
opGT = gt, 2;
opGE = ge, 2;
}
priority 7 {
opEQ = eq, 2;
opNE = excleq, 2;
}
priority 8 {
opAnd = "and", 2;
}
priority 9 {
opOr = "or", 2;
}
}
token COMMENT : endOfLine(start = "--");
lexer = "
%options testLiterals = false;
NL
: ( '\\r' '\\n'
| '\\n' '\\r' //Improbable
| '\\r'
| '\\n'
)
{newline();}
;
WS
: ( ' '
| '\\t'
)
;
%protected
DIGIT
: '0'..'9'
;
%protected
ALPHA
: 'a'..'z'
| 'A'..'Z'
| '_'
//For Unicode compatibility (from 0000 to 00ff)
| '\\u00C0' .. '\\u00D6'
| '\\u00D8' .. '\\u00F6'
| '\\u00F8' .. '\\u00FF'
;
%protected
SNAME
%v2 options {
%v2 testLiterals = true;
%v2 }
: (ALPHA) (ALPHA | DIGIT)*
;
NAME
: (
%v3 SNAME
%v2 s:SNAME {if(s.getType() != SNAME) $setType(s.getType());}
| '\"'!
( ESC
| '\\n' {newline();}
| ~('\\\\'|'\\\"'|'\\n')
)*
'\"'!
%v3 {setText(ei.unescapeString(getText(), 1));}
)
;
INT
: (DIGIT)+
%v2 (('.' DIGIT)=> '.' (DIGIT)+ {$setType(FLOAT);})?
;
%v3 FLOAT : DIGIT+ (('.' DIGIT)=>'.' DIGIT+)? ; // cannot accept DIGIT '.' because it would conflict with Navigation
%protected
ESC
: '\\\\'!
( 'n' %v2{%setText(\"\\n\");}
| 'r' %v2{%setText(\"\\r\");}
| 't' %v2{%setText(\"\\t\");}
| 'b' %v2{%setText(\"\\b\");}
| 'f' %v2{%setText(\"\\f\");}
| '\"' %v2{%setText(\"\\\"\");}
| '\\'' %v2{%setText(\"\\'\");}
| '\\\\' %v2{%setText(\"\\\\\");}
| (
('0'..'3')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: ('0'..'7')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: '0'..'7'
)?
)?
| ('4'..'7')
(
%v2 options {
%v2 warnWhenFollowAmbig = false;
%v2 }
: ('0'..'7')
)?
)
{
%v2 String s = %getText;
%v2 int i;
%v2 int ret = 0;
%v2 String ans;
%v2 for (i=0; i<s.length(); ++i)
%v2 ret = ret*8 + s.charAt(i) - '0';
%v2 ans = String.valueOf((char) ret);
%v2 %setText(ans);
}
)
;
STRING
: '\\''!
( ESC
| '\\n' {newline();}
| ~('\\\\'|'\\''|'\\n')
)*
'\\''!
%v3 {setText(ei.unescapeString(getText(), 1));}
;
";
}