;
path:
- path_rev { List.rev $1 }
+ separated_nonempty_list(PIPE, simple_path) { $1 }
;
-path_rev:
- simple_path { [ $1 ] }
-| path_rev PIPE simple_path { $3 :: $1 }
-;
-
-
simple_path:
absolute_path { Absolute (List.rev $1) }
| relative_path { Relative (List.rev $1) }
step is always a small list, of size 1-3 so @ is
cheap
*/
+
relative_path:
step { $1 }
| relative_path SLASH step { $3 @ $1 }
test:
NODE { node, NodeKind.Node }
| TEXT { text, NodeKind.Text }
-| STAR { star, NodeKind.Element }
+| STAR { node, NodeKind.Element }
| COMMENT { QNameSet.singleton(QName.comment),
NodeKind.Comment
}
| FLOAT { Number(`Float($1)) }
| STRING { String $1 }
| SUB expr %prec uminus { Unop(Neg, $2) }
-| expr AND expr { Binop($1, And, $3) }
-| expr OR expr { Binop($1, Or, $3) }
-| expr ADD expr { Binop($1, Add, $3) }
-| expr SUB expr { Binop($1, Sub, $3) }
-| expr STAR expr { Binop($1, Mult, $3) }
-| expr DIV expr { Binop($1, Div, $3) }
-| expr MOD expr { Binop($1, Mod, $3) }
-| expr EQ expr { Binop($1, Eq, $3) }
-| expr NEQ expr { Binop($1, Neq, $3) }
-| expr LT expr { Binop($1, Lt, $3) }
-| expr LTE expr { Binop($1, Lte, $3) }
-| expr GT expr { Binop($1, Gt, $3) }
-| expr GTE expr { Binop($1, Gte, $3) }
+| e1 = expr; op = binop; e2 = expr { Binop(e1, op, e2) }
| TAG LP arg_list RP { Fun_call(QName.of_string $1, $3) }
| LP expr RP { $2 }
| path { Path $1 }
;
+%inline binop:
+| AND { And }
+| OR { Or }
+| ADD { Add }
+| SUB { Sub }
+| STAR { Mult }
+| DIV { Div }
+| MOD { Mod }
+| EQ { Eq }
+| NEQ { Neq }
+| LT { Lt }
+| LTE { Lte }
+| GT { Gt }
+| GTE { Gte }
+;
arg_list:
{ [] }
| arg_list1 { List.rev $1 }