(***********************************************************************) (* *) (* 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: *) 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