Simplify the automaton encoding a bit (remove redundant predicates in formulae).
[tatoo.git] / src / xpath / ast.ml
index c3c00d9..5b322a4 100644 (file)
 (*                                                                     *)
 (***********************************************************************)
 
-(*
-  Time-stamp: <Last modified on 2013-02-07 10:04:30 CET by Kim Nguyen>
-*)
-
-open Utils
-
 type path = single_path list
 and single_path = Absolute of step list | Relative of step list
 and step = axis * test * expr list
-and axis = Self | Attribute | Child | Descendant | DescendantOrSelf | FollowingSibling
-           | Parent | Ancestor | AncestorOrSelf | PrecedingSibling | Preceding | Following
+and axis = Self | Attribute | Child
+           | Descendant of bool  (* true = descendant-or-self, false = descendant *)
+           | FollowingSibling
+           | Parent
+           | Ancestor of bool (* true = ancestor-or-self, false = ancestor *)
+           | PrecedingSibling
+           | Preceding | Following
 
-and test = QNameSet.t
+and test = QNameSet.t * Tree.NodeKind.t
 
 and binop = Eq | Neq | Lt | Gt | Lte | Gte | Or | And | Add | Sub | Mult | Div | Mod
 and unop =  Neg
@@ -47,7 +46,6 @@ let star =
   QNameSet.complement (
     QNameSet.from_list [ QName.text;
                          QName.document;
-                         QName.cdata_section;
                          QName.comment])
 
 
@@ -111,30 +109,37 @@ and print_axis fmt a = pp fmt "%s" begin
   match a with
     Self -> "self"
   | Child -> "child"
-  | Descendant -> "descendant"
-  | DescendantOrSelf -> "descendant-or-self"
+  | Descendant false -> "descendant"
+  | Descendant true -> "descendant-or-self"
   | FollowingSibling -> "following-sibling"
   | Attribute -> "attribute"
-  | Ancestor -> "ancestor"
-  | AncestorOrSelf -> "ancestor-or-self"
+  | Ancestor false -> "ancestor"
+  | Ancestor true -> "ancestor-or-self"
   | PrecedingSibling -> "preceding-sibling"
   | Parent -> "parent"
   | Preceding -> "preceding"
   | Following -> "following"
 end
 
-and print_test fmt ts =
-  try
-    pp fmt "%s" (List.assoc ts
-                   [ text,"text()";
-                     node,"node()";
-                     star, "*" ] )
-  with
-    Not_found -> pp fmt "%s"
-      (if QNameSet.is_finite ts
-       then QName.to_string (QNameSet.choose ts)
-       else "<INFINITE>"
-      )
+and print_test fmt (ts,kind) =
+  let open Tree.NodeKind in
+    match kind with
+      Text -> pp fmt "%s" "text()"
+    | Element | Attribute ->
+        pp fmt "%s" begin
+          if QNameSet.is_finite ts then
+            QName.to_string (QNameSet.choose ts)
+          else "*"
+        end
+    | Comment -> pp fmt "%s" "comment()"
+    | ProcessingInstruction ->
+        pp fmt "processing-instruction(%s)"
+          begin
+            if ts == star then ""
+            else "\"" ^ (QName.to_string  (QNameSet.choose ts)) ^ "\""
+          end
+    | Node -> pp fmt "%s" "node()"
+    | Document -> pp fmt "%s" "<DOCUMENT>"
 
 and print_expr fmt = function
 | Number (`Int(i)) -> pp fmt "%i" i
@@ -163,3 +168,17 @@ and print_expr fmt = function
     print_expr fmt e0;
     if need_par0 then pp fmt ")"
 
+
+
+let invert_axis = function
+| Self -> Self
+| Attribute -> Parent (* Improve *)
+| Child -> Parent
+| Descendant (b) -> Ancestor (b)
+| FollowingSibling -> PrecedingSibling
+| Parent -> Child
+| Ancestor (b) -> Descendant (b)
+| PrecedingSibling -> FollowingSibling
+| Preceding -> Following
+| Following -> Preceding
+;;