Fix a bug in the handling of processing-instruction() test.
[tatoo.git] / src / xpath / xpath_internal_parser.mly
index de63cdf..a40eea9 100644 (file)
 (***********************************************************************)
 
 (*
-  Time-stamp: <Last modified on 2013-03-09 16:56:45 CET by Kim Nguyen>
+  Time-stamp: <Last modified on 2013-03-13 12:38:54 CET by Kim Nguyen>
 *)
 
   open Ast
-  let f () = ()
+  open Tree.Common
 %}
 
 %token <string> TAG
+%token <string> PI
+%token <string> ATTNAME
 %token <string> STRING
 %token <int>  INT
 %token <float> FLOAT
@@ -30,7 +32,7 @@
 %token RB LB LP RP
 %token SLASH SLASHSLASH COLONCOLON STAR PIPE
 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
-%token NODE TEXT
+%token NODE TEXT COMMENT
 %token COMMA
 %token EOF
 
@@ -68,37 +70,81 @@ simple_path:
 
 absolute_path:
   SLASH relative_path { $2 }
-| SLASHSLASH relative_path { $2 @ [(Descendant true, node, [])] }
+| SLASHSLASH relative_path { $2 @
+                               [(Descendant true,
+                                 (node, NodeKind.Node),
+                                 [])] }
 ;
 
+/*
+  step is always a small list, of size 1-3 so @ is
+  cheap
+*/
 relative_path:
-  step { [ $1 ] }
-| relative_path SLASH step { $3 :: $1 }
-| relative_path SLASHSLASH step { $3
-                                  :: (Descendant true, node, [])
-                                  :: $1 }
+  step { $1 }
+| relative_path SLASH step { $3 @ $1 }
+| relative_path SLASHSLASH step { $3 @
+                                    ((Descendant true,
+                                      (node, NodeKind.Node),
+                                      [])
+                                     :: $1) }
 ;
 
 step:
-  axis_test pred_list    { let a, b = $1 in a, b, $2 }
+  axis_test pred_list    {
+    match $1 with
+      (a,b) :: r -> (a,b,$2) :: (List.map (fun (a,b) -> (a,b,[])) r)
+    | [] -> assert false
+  }
 ;
 
 axis_test:
-  AXIS COLONCOLON test  { $1, $3 }
-| test                  { Child, $1 }
+  AXIS COLONCOLON test  { let a, (t,k) = $1, $3 in
+                          match a with
+                            Attribute when Utils.QNameSet.is_finite t ->
+                              [ a, ((Utils.QNameSet.fold
+                                       (fun t a ->
+                                         Utils.QNameSet.add
+                                           (Utils.QName.attribute t) a)
+                                       t Utils.QNameSet.empty), k) ]
+                          | Preceding|Following ->
+                              [ (Descendant true, (t,k));
+                                if a == Preceding then
+                                  (PrecedingSibling, (node, NodeKind.Node))
+                                else
+                                  (FollowingSibling, (node, NodeKind.Node));
+                                (Ancestor true, (node, NodeKind.Node)) ]
+
+                          | _ -> [ a, (t,k) ]
+                        }
+| test                  { [ Child, $1 ] }
 | AXIS            {
   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)
+  [Child, (Utils.QNameSet.singleton (Utils.QName.of_string a),NodeKind.Element)]
 }
+| ATTNAME             {  [(Attribute,
+                           (Utils.QNameSet.singleton (Utils.QName.of_string $1),
+                            NodeKind.Attribute))] }
 ;
 
 test:
-  NODE                { node }
-| TEXT                { text }
-| STAR                { star }
-| TAG                 { Utils.QNameSet.singleton(Utils.QName.of_string $1) }
+  NODE                { node, NodeKind.Node }
+| TEXT                { text, NodeKind.Text }
+| STAR                { star, NodeKind.Element }
+| COMMENT             { Utils.QNameSet.singleton(Utils.QName.comment),
+                        NodeKind.Comment
+                      }
+| PI                  { (if $1 = "" then star
+                         else Utils.QNameSet.singleton(
+                           Utils.QName.processing_instruction (
+                             Utils.QName.of_string $1)
+                         )), NodeKind.ProcessingInstruction
+                      }
+| TAG                 { Utils.QNameSet.singleton(Utils.QName.of_string $1),
+                        NodeKind.Element
+                      }
 ;
 
 pred_list:
@@ -142,4 +188,3 @@ arg_list1:
   expr                     { [ $1 ] }
 | arg_list1 COMMA expr     { $3 :: $1 }
 ;
-