Compilation of the axis part of an XPath expression.
authorKim Nguyễn <kn@lri.fr>
Mon, 11 Feb 2013 17:54:28 +0000 (18:54 +0100)
committerKim Nguyễn <kn@lri.fr>
Mon, 4 Mar 2013 18:00:02 +0000 (19:00 +0100)
src/test.ml
src/xpath.mlpack
src/xpath/compile.ml [new file with mode: 0644]

index e854f44..f62e68d 100644 (file)
@@ -14,7 +14,7 @@
 (***********************************************************************)
 
 (*
-  Time-stamp: <Last modified on 2013-02-07 10:25:30 CET by Kim Nguyen>
+  Time-stamp: <Last modified on 2013-02-11 22:41:35 CET by Kim Nguyen>
 *)
 
 (** use: xml_file "XPath querie"
@@ -24,6 +24,8 @@
 
 module F = Auto.Formula
 module A = Auto.Ata
+module X = Xpath.Compile
+
 (* to force ocaml build to add Formula to the dependency chain even if
    we don't use it yet*)
 
index 7619c15..a4ae491 100644 (file)
@@ -1,4 +1,5 @@
 xpath/Ast
+xpath/Compile
 xpath/Parser
 xpath/Ulexer
 xpath/Xpath_internal_parser
diff --git a/src/xpath/compile.ml b/src/xpath/compile.ml
new file mode 100644 (file)
index 0000000..a84a50f
--- /dev/null
@@ -0,0 +1,102 @@
+(***********************************************************************)
+(*                                                                     *)
+(*                               TAToo                                 *)
+(*                                                                     *)
+(*                     Kim Nguyen, LRI UMR8623                         *)
+(*                   Université Paris-Sud & CNRS                       *)
+(*                                                                     *)
+(*  Copyright 2010-2013 Université Paris-Sud and Centre National de la *)
+(*  Recherche Scientifique. All rights reserved.  This file is         *)
+(*  distributed under the terms of the GNU Lesser General Public       *)
+(*  License, with the special exception on linking described in file   *)
+(*  ../LICENSE.                                                        *)
+(*                                                                     *)
+(***********************************************************************)
+
+(*
+  Time-stamp: <Last modified on 2013-02-12 08:32:59 CET by Kim Nguyen>
+*)
+
+open Ast
+open Auto
+open Utils
+
+let mk_atom l b q =
+  Ata.SFormula.atom_ (Ata.Move.make (l,b,q))
+
+let ( => ) a b = (a, b)
+let ( ** ) l q = mk_atom l true q
+let ( ++ ) a b = Ata.SFormula.or_ a b
+let ( %% ) a b = Ata.SFormula.and_ a b
+let ( @: ) a b = StateSet.add a b
+
+
+let compile_axis_test ax tst inq trs sts =
+  match ax with
+  | Self ->
+      let outq = State.make () in
+      outq,
+      (inq, [ tst =>  (`Epsilon ** outq ) ]) :: trs,
+      outq @: sts
+
+  | Child ->
+      let outq = State.make () in
+      let outq' = State.make () in
+      outq',
+      (inq, [ QNameSet.any => (`Left ** outq)])
+      :: (outq, [ tst => (`Epsilon ** outq');
+                  QNameSet.any => (`Right ** outq) ])
+      :: trs,
+      outq @: (outq' @: sts)
+
+  | Descendant | DescendantOrSelf ->
+      let dir = if ax = Descendant then `Left else `Epsilon in
+      let outq = State.make () in
+      let outq' = State.make () in
+      outq',
+      (inq, [ QNameSet.any => (dir ** outq)])
+      :: (outq, [ tst =>  (`Epsilon ** outq');
+                  QNameSet.any => ((`Left ** outq) ++ (`Right ** outq))
+                ])
+      :: trs,
+      outq @: (outq' @: sts)
+
+  | Parent ->
+      let outq = State.make () in
+      let outq' = State.make () in
+      let outq'' = State.make () in
+      let move = (`Up1 ** outq') ++ (`Up2 ** outq) in
+      outq'',
+      (inq, [QNameSet.any => move ])
+      :: (outq, [ QNameSet.any => move ])
+      :: (outq', [ tst => (`Epsilon ** outq'') ])
+      :: trs,
+      outq @: (outq' @: (outq'' @: sts))
+
+  | Ancestor | AncestorOrSelf ->
+      let outq = State.make () in
+      let outq' = State.make () in
+      let outq'' = State.make () in
+      let move =
+        (if ax = Ancestor then (`Up1 ** outq')
+         else (`Epsilon ** outq')) ++ (`Up1 ** outq) ++ (`Up2 ** outq)
+      in
+      outq'',
+      (inq, [QNameSet.any => move  ])
+      :: (outq, [ QNameSet.any => move ])
+      :: (outq', [ tst => (`Epsilon ** outq'') ])
+      :: trs,
+      outq @: (outq' @: (outq'' @: sts))
+
+  | FollowingSibling | PrecedingSibling ->
+      let outq = State.make () in
+      let outq' = State.make () in
+      let dir = if ax = FollowingSibling then `Right else `Up2 in
+      outq',
+      (inq, [ QNameSet.any => (dir ** outq) ])
+      :: (outq, [ tst => (`Epsilon ** outq');
+                  QNameSet.any => (dir ** outq) ])
+      :: trs,
+      outq @: (outq' @: sts)
+
+  | _ -> assert false