%{ (***********************************************************************) (* *) (* TAToo *) (* *) (* Kim Nguyen, LRI UMR8623 *) (* Université Paris-Sud & CNRS *) (* *) (* Copyright 2010-2012 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 let f () = () %} %token TAG %token STRING %token INT %token FLOAT %token AXIS %token RB LB LP RP %token SLASH SLASHSLASH COLONCOLON STAR PIPE %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD %token NODE TEXT %token COMMA %token EOF %left OR %left AND %left EQ NEQ %left LT GT LTE GTE %left ADD SUB %left MOD DIV STAR %nonassoc uminus %start xpath_query %type xpath_query %% xpath_query: path EOF { $1 } ; path: path_rev { List.rev $1 } ; path_rev: simple_path { [ $1 ] } | path_rev PIPE simple_path { $3 :: $1 } ; simple_path: absolute_path { Absolute (List.rev $1) } | relative_path { Relative (List.rev $1) } ; absolute_path: SLASH relative_path { $2 } | SLASHSLASH relative_path { $2 @ [(Descendant true, node, [])] } ; relative_path: step { [ $1 ] } | relative_path SLASH step { $3 :: $1 } | relative_path SLASHSLASH step { $3 :: (Descendant true, node, []) :: $1 } ; step: axis_test pred_list { let a, b = $1 in a, b, $2 } ; axis_test: AXIS COLONCOLON test { let a, t = $1, $3 in if a == Attribute && Utils.QNameSet.is_finite t then (a, Utils.QNameSet.fold (fun t a -> Utils.QNameSet.add (Utils.QName.add_attribute_prefix t) a) t Utils.QNameSet.empty) else (a, t) } | 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) } ; test: NODE { node } | TEXT { text } | STAR { star } | TAG { Utils.QNameSet.singleton(Utils.QName.of_string $1) } ; pred_list: pred_list_rev { List.rev $1 } ; pred_list_rev: { [] } | pred_list LB expr RB { $3 :: $1 } ; expr: INT { Number(`Int($1)) } | FLOAT { Number(`Float($1)) } | STRING { String $1 } | SUB expr %prec uminus { Unop(Neg, $2) } | expr AND expr { Binop($1, And, $3) } | expr OR expr { Binop($1, Or, $3) } | expr ADD expr { Binop($1, Add, $3) } | expr SUB expr { Binop($1, Sub, $3) } | expr STAR expr { Binop($1, Mult, $3) } | expr DIV expr { Binop($1, Div, $3) } | expr MOD expr { Binop($1, Mod, $3) } | expr EQ expr { Binop($1, Eq, $3) } | expr NEQ expr { Binop($1, Neq, $3) } | expr LT expr { Binop($1, Lt, $3) } | expr LTE expr { Binop($1, Lte, $3) } | expr GT expr { Binop($1, Gt, $3) } | expr GTE expr { Binop($1, Gte, $3) } | TAG LP arg_list RP { Fun_call(Utils.QName.of_string $1, $3) } | LP expr RP { $2 } | path { Path $1 } ; arg_list: { [] } | arg_list1 { List.rev $1 } ; arg_list1: expr { [ $1 ] } | arg_list1 COMMA expr { $3 :: $1 } ;