Add support for following and preceding using the usual encoding:
authorKim Nguyễn <kn@lri.fr>
Wed, 13 Mar 2013 11:35:04 +0000 (12:35 +0100)
committerKim Nguyễn <kn@lri.fr>
Wed, 13 Mar 2013 11:35:04 +0000 (12:35 +0100)
axis = ancestor-or-self::node()/axis-sibling::node()/descendant-or-self

src/xpath/xpath_internal_parser.mly

index a589fde..72a07fb 100644 (file)
@@ -15,7 +15,7 @@
 (***********************************************************************)
 
 (*
-  Time-stamp: <Last modified on 2013-03-13 09:56:09 CET by Kim Nguyen>
+  Time-stamp: <Last modified on 2013-03-13 12:11:04 CET by Kim Nguyen>
 *)
 
   open Ast
@@ -76,43 +76,57 @@ 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 }
-| relative_path SLASHSLASH step { $3
-                                  :: (Descendant true,
+  step { $1 }
+| relative_path SLASH step { $3 @ $1 }
+| relative_path SLASHSLASH step { $3 @
+                                    ((Descendant true,
                                       (node, NodeKind.Node),
                                       [])
-                                  :: $1 }
+                                     :: $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  { let a, (t,k) = $1, $3 in
-                          let new_t = 
-                            if a == Attribute && Utils.QNameSet.is_finite t then
-                              Utils.QNameSet.fold
-                                (fun t a ->
-                                  Utils.QNameSet.add
-                                    (Utils.QName.attribute t) a)
-                                t Utils.QNameSet.empty
-                            else t
-                          in
-                          (a, (new_t,k))
+                          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 }
+| 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),NodeKind.Element)
+  [Child, (Utils.QNameSet.singleton (Utils.QName.of_string a),NodeKind.Element)]
 }
-| ATTNAME             {  (Attribute,
-                          (Utils.QNameSet.singleton (Utils.QName.of_string $1),
-                          NodeKind.Attribute)) }
+| ATTNAME             {  [(Attribute,
+                           (Utils.QNameSet.singleton (Utils.QName.of_string $1),
+                            NodeKind.Attribute))] }
 ;
 
 test: