3651d2cd9e547a0e2ff239bdcbe61c40f64da233
[tatoo.git] / src / xpath / xpath_internal_parser.mly
1 %{
2 (***********************************************************************)
3 (*                                                                     *)
4 (*                               TAToo                                 *)
5 (*                                                                     *)
6 (*                     Kim Nguyen, LRI UMR8623                         *)
7 (*                   Université Paris-Sud & CNRS                       *)
8 (*                                                                     *)
9 (*  Copyright 2010-2012 Université Paris-Sud and Centre National de la *)
10 (*  Recherche Scientifique. All rights reserved.  This file is         *)
11 (*  distributed under the terms of the GNU Lesser General Public       *)
12 (*  License, with the special exception on linking described in file   *)
13 (*  ../LICENSE.                                                        *)
14 (*                                                                     *)
15 (***********************************************************************)
16
17 (*
18   Time-stamp: <Last modified on 2013-03-10 14:31:48 CET by Kim Nguyen>
19 *)
20
21   open Ast
22   let f () = ()
23 %}
24
25 %token <string> TAG
26 %token <string> ATTNAME
27 %token <string> STRING
28 %token <int>  INT
29 %token <float> FLOAT
30 %token <Ast.axis> AXIS
31 %token RB LB LP RP
32 %token SLASH SLASHSLASH COLONCOLON STAR PIPE
33 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
34 %token NODE TEXT
35 %token COMMA
36 %token EOF
37
38 %left OR
39 %left AND
40 %left EQ NEQ
41 %left LT GT LTE GTE
42 %left ADD SUB
43 %left MOD DIV STAR
44 %nonassoc uminus
45
46 %start xpath_query
47 %type <Ast.path> xpath_query
48
49
50 %%
51 xpath_query:
52 path EOF          { $1 }
53 ;
54
55 path:
56   path_rev { List.rev $1 }
57 ;
58
59 path_rev:
60   simple_path     { [ $1 ] }
61 | path_rev PIPE simple_path { $3 :: $1 }
62 ;
63
64
65 simple_path:
66    absolute_path  { Absolute  (List.rev $1) }
67 |  relative_path  { Relative  (List.rev $1) }
68 ;
69
70 absolute_path:
71   SLASH relative_path { $2 }
72 | SLASHSLASH relative_path { $2 @ [(Descendant true, node, [])] }
73 ;
74
75 relative_path:
76   step { [ $1 ] }
77 | relative_path SLASH step { $3 :: $1 }
78 | relative_path SLASHSLASH step { $3
79                                   :: (Descendant true, node, [])
80                                   :: $1 }
81 ;
82
83 step:
84   axis_test pred_list    { let a, b = $1 in a, b, $2 }
85 ;
86
87 axis_test:
88   AXIS COLONCOLON test  { let a, t = $1, $3 in
89                           if a == Attribute && Utils.QNameSet.is_finite t then
90                             (a, Utils.QNameSet.fold
91                               (fun t a ->
92                                 Utils.QNameSet.add
93                                   (Utils.QName.add_attribute_prefix t) a)
94                               t Utils.QNameSet.empty)
95                           else
96                             (a, t)
97                         }
98 | test                  { Child, $1 }
99 | AXIS            {
100   let _ = Format.flush_str_formatter () in
101   let () = Format.fprintf Format.str_formatter "%a" Ast.print_axis $1 in
102   let a = Format.flush_str_formatter () in
103   Child, Utils.QNameSet.singleton (Utils.QName.of_string a)
104 }
105 | ATTNAME             {  (Attribute,
106                           Utils.QNameSet.singleton (Utils.QName.of_string $1)) }
107 ;
108
109 test:
110   NODE                { node }
111 | TEXT                { text }
112 | STAR                { star }
113 | TAG                 { Utils.QNameSet.singleton(Utils.QName.of_string $1) }
114 ;
115
116 pred_list:
117   pred_list_rev             { List.rev $1 }
118 ;
119
120 pred_list_rev:
121              { [] }
122 | pred_list LB expr RB   { $3 :: $1 }
123 ;
124
125 expr:
126   INT                       { Number(`Int($1)) }
127 | FLOAT                     { Number(`Float($1)) }
128 | STRING                    { String $1 }
129 | SUB expr     %prec uminus { Unop(Neg, $2) }
130 | expr AND expr             { Binop($1, And, $3) }
131 | expr OR expr              { Binop($1, Or, $3) }
132 | expr ADD expr             { Binop($1, Add, $3) }
133 | expr SUB expr             { Binop($1, Sub, $3) }
134 | expr STAR expr            { Binop($1, Mult, $3) }
135 | expr DIV expr             { Binop($1, Div, $3) }
136 | expr MOD expr             { Binop($1, Mod, $3) }
137 | expr EQ expr              { Binop($1, Eq, $3) }
138 | expr NEQ expr             { Binop($1, Neq, $3) }
139 | expr LT expr              { Binop($1, Lt, $3) }
140 | expr LTE expr             { Binop($1, Lte, $3) }
141 | expr GT expr              { Binop($1, Gt, $3) }
142 | expr GTE expr             { Binop($1, Gte, $3) }
143 | TAG LP arg_list RP        { Fun_call(Utils.QName.of_string $1, $3) }
144 | LP expr RP                { $2 }
145 | path                      { Path $1 }
146 ;
147
148 arg_list:
149                             { [] }
150 | arg_list1                 { List.rev $1 }
151 ;
152
153 arg_list1:
154   expr                     { [ $1 ] }
155 | arg_list1 COMMA expr     { $3 :: $1 }
156 ;