Refactor pretty printing of transitions and fix some depracated function uses.
[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   open Ast
18   open Tree
19 %}
20
21 %token <string> TAG
22 %token <string> PI
23 %token <string> ATTNAME
24 %token <string> STRING
25 %token <int>  INT
26 %token <float> FLOAT
27 %token <Ast.axis> AXIS
28 %token RB LB LP RP
29 %token SLASH SLASHSLASH COLONCOLON STAR PIPE DOT DOTDOT
30 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
31 %token NODE TEXT COMMENT
32 %token COMMA
33 %token EOF
34
35 %left OR
36 %left AND
37 %left EQ NEQ
38 %left LT GT LTE GTE
39 %left ADD SUB
40 %left MOD DIV STAR
41 %nonassoc uminus
42
43 %start xpath_query
44 %type <Ast.path> xpath_query
45
46
47 %%
48 xpath_query:
49 path EOF          { $1 }
50 ;
51
52 path:
53   path_rev { List.rev $1 }
54 ;
55
56 path_rev:
57   simple_path     { [ $1 ] }
58 | path_rev PIPE simple_path { $3 :: $1 }
59 ;
60
61
62 simple_path:
63    absolute_path  { Absolute  (List.rev $1) }
64 |  relative_path  { Relative  (List.rev $1) }
65 ;
66
67 absolute_path:
68   SLASH relative_path { $2 }
69 | SLASHSLASH relative_path { $2 @
70                                [(Descendant true,
71                                  (node, NodeKind.Node),
72                                  [])] }
73 ;
74
75 /*
76   step is always a small list, of size 1-3 so @ is
77   cheap
78 */
79 relative_path:
80   step { $1 }
81 | relative_path SLASH step { $3 @ $1 }
82 | relative_path SLASHSLASH step { $3 @
83                                     ((Descendant true,
84                                       (node, NodeKind.Node),
85                                       [])
86                                      :: $1) }
87 ;
88
89 step:
90   DOT                    { [ (Self, (node, NodeKind.Node), []) ] }
91 | DOTDOT                 { [ (Parent, (node, NodeKind.Node), []) ] }
92 | axis_test pred_list    {
93     match $1 with
94       (a,b) :: r -> (a,b,$2) :: (List.map (fun (a,b) -> (a,b,[])) r)
95     | [] -> assert false
96   }
97 ;
98
99 axis_test:
100   AXIS COLONCOLON test  { let a, (t,k) = $1, $3 in
101                           match a with
102                             Attribute when QNameSet.is_finite t ->
103                               [ a, ((QNameSet.fold
104                                        (fun t a ->
105                                          QNameSet.add
106                                            (QName.attribute t) a)
107                                        t QNameSet.empty), k) ]
108                           | Preceding|Following ->
109                               [ (Descendant true, (t,k));
110                                 if a == Preceding then
111                                   (PrecedingSibling, (node, NodeKind.Node))
112                                 else
113                                   (FollowingSibling, (node, NodeKind.Node));
114                                 (Ancestor true, (node, NodeKind.Node)) ]
115
116                           | _ -> [ a, (t,k) ]
117                         }
118 | test                  { [ Child, $1 ] }
119 | AXIS            {
120   let _ = Format.flush_str_formatter () in
121   let () = Format.fprintf Format.str_formatter "%a" Ast.print_axis $1 in
122   let a = Format.flush_str_formatter () in
123   [Child, (QNameSet.singleton (QName.of_string a),NodeKind.Element)]
124 }
125 | ATTNAME             {  [(Attribute,
126                            (QNameSet.singleton (QName.of_string $1),
127                             NodeKind.Attribute))] }
128 ;
129
130 test:
131   NODE                { node, NodeKind.Node }
132 | TEXT                { text, NodeKind.Text }
133 | STAR                { node, NodeKind.Element }
134 | COMMENT             { QNameSet.singleton(QName.comment),
135                         NodeKind.Comment
136                       }
137 | PI                  { (if $1 = "" then star
138                          else QNameSet.singleton(
139                            QName.processing_instruction (
140                              QName.of_string $1)
141                          )), NodeKind.ProcessingInstruction
142                       }
143 | TAG                 { QNameSet.singleton(QName.of_string $1),
144                         NodeKind.Element
145                       }
146 ;
147
148 pred_list:
149   pred_list_rev             { List.rev $1 }
150 ;
151
152 pred_list_rev:
153              { [] }
154 | pred_list LB expr RB   { $3 :: $1 }
155 ;
156
157 expr:
158   INT                       { Number(`Int($1)) }
159 | FLOAT                     { Number(`Float($1)) }
160 | STRING                    { String $1 }
161 | SUB expr     %prec uminus { Unop(Neg, $2) }
162 | expr AND expr             { Binop($1, And, $3) }
163 | expr OR expr              { Binop($1, Or, $3) }
164 | expr ADD expr             { Binop($1, Add, $3) }
165 | expr SUB expr             { Binop($1, Sub, $3) }
166 | expr STAR expr            { Binop($1, Mult, $3) }
167 | expr DIV expr             { Binop($1, Div, $3) }
168 | expr MOD expr             { Binop($1, Mod, $3) }
169 | expr EQ expr              { Binop($1, Eq, $3) }
170 | expr NEQ expr             { Binop($1, Neq, $3) }
171 | expr LT expr              { Binop($1, Lt, $3) }
172 | expr LTE expr             { Binop($1, Lte, $3) }
173 | expr GT expr              { Binop($1, Gt, $3) }
174 | expr GTE expr             { Binop($1, Gte, $3) }
175 | TAG LP arg_list RP        { Fun_call(QName.of_string $1, $3) }
176 | LP expr RP                { $2 }
177 | path                      { Path $1 }
178 ;
179
180 arg_list:
181                             { [] }
182 | arg_list1                 { List.rev $1 }
183 ;
184
185 arg_list1:
186   expr                     { [ $1 ] }
187 | arg_list1 COMMA expr     { $3 :: $1 }
188 ;