Cherry pick use of menhir features from branch feature/menhir.
[tatoo.git] / src / xpath / xpath_internal_parser.mly
index a40eea9..f0207ea 100644 (file)
 (*                                                                     *)
 (***********************************************************************)
 
-(*
-  Time-stamp: <Last modified on 2013-03-13 12:38:54 CET by Kim Nguyen>
-*)
-
   open Ast
-  open Tree.Common
+  open Tree
 %}
 
 %token <string> TAG
@@ -30,7 +26,7 @@
 %token <float> FLOAT
 %token <Ast.axis> AXIS
 %token RB LB LP RP
-%token SLASH SLASHSLASH COLONCOLON STAR PIPE
+%token SLASH SLASHSLASH COLONCOLON STAR PIPE DOT DOTDOT
 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
 %token NODE TEXT COMMENT
 %token COMMA
@@ -54,15 +50,9 @@ path EOF          { $1 }
 ;
 
 path:
-  path_rev { List.rev $1 }
-;
-
-path_rev:
-  simple_path     { [ $1 ] }
-| path_rev PIPE simple_path { $3 :: $1 }
+  separated_nonempty_list(PIPE, simple_path)  { $1 }
 ;
 
-
 simple_path:
    absolute_path  { Absolute  (List.rev $1) }
 |  relative_path  { Relative  (List.rev $1) }
@@ -80,6 +70,7 @@ absolute_path:
   step is always a small list, of size 1-3 so @ is
   cheap
 */
+
 relative_path:
   step { $1 }
 | relative_path SLASH step { $3 @ $1 }
@@ -91,7 +82,9 @@ relative_path:
 ;
 
 step:
-  axis_test pred_list    {
+  DOT                    { [ (Self, (node, NodeKind.Node), []) ] }
+| DOTDOT                 { [ (Parent, (node, NodeKind.Node), []) ] }
+| axis_test pred_list    {
     match $1 with
       (a,b) :: r -> (a,b,$2) :: (List.map (fun (a,b) -> (a,b,[])) r)
     | [] -> assert false
@@ -101,12 +94,12 @@ step:
 axis_test:
   AXIS COLONCOLON test  { let a, (t,k) = $1, $3 in
                           match a with
-                            Attribute when Utils.QNameSet.is_finite t ->
-                              [ a, ((Utils.QNameSet.fold
+                            Attribute when QNameSet.is_finite t ->
+                              [ a, ((QNameSet.fold
                                        (fun t a ->
-                                         Utils.QNameSet.add
-                                           (Utils.QName.attribute t) a)
-                                       t Utils.QNameSet.empty), k) ]
+                                         QNameSet.add
+                                           (QName.attribute t) a)
+                                       t QNameSet.empty), k) ]
                           | Preceding|Following ->
                               [ (Descendant true, (t,k));
                                 if a == Preceding then
@@ -122,27 +115,27 @@ axis_test:
   let _ = Format.flush_str_formatter () in
   let () = Format.fprintf Format.str_formatter "%a" Ast.print_axis $1 in
   let a = Format.flush_str_formatter () in
-  [Child, (Utils.QNameSet.singleton (Utils.QName.of_string a),NodeKind.Element)]
+  [Child, (QNameSet.singleton (QName.of_string a),NodeKind.Element)]
 }
 | ATTNAME             {  [(Attribute,
-                           (Utils.QNameSet.singleton (Utils.QName.of_string $1),
+                           (QNameSet.singleton (QName.of_string $1),
                             NodeKind.Attribute))] }
 ;
 
 test:
   NODE                { node, NodeKind.Node }
 | TEXT                { text, NodeKind.Text }
-| STAR                { star, NodeKind.Element }
-| COMMENT             { Utils.QNameSet.singleton(Utils.QName.comment),
+| STAR                { node, NodeKind.Element }
+| COMMENT             { QNameSet.singleton(QName.comment),
                         NodeKind.Comment
                       }
 | PI                  { (if $1 = "" then star
-                         else Utils.QNameSet.singleton(
-                           Utils.QName.processing_instruction (
-                             Utils.QName.of_string $1)
+                         else QNameSet.singleton(
+                           QName.processing_instruction (
+                             QName.of_string $1)
                          )), NodeKind.ProcessingInstruction
                       }
-| TAG                 { Utils.QNameSet.singleton(Utils.QName.of_string $1),
+| TAG                 { QNameSet.singleton(QName.of_string $1),
                         NodeKind.Element
                       }
 ;
@@ -161,24 +154,27 @@ expr:
 | 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) }
-| TAG LP arg_list RP        { Fun_call(Utils.QName.of_string $1, $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 }