--- /dev/null
+(***********************************************************************)
+(* *)
+(* 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