Merge branch 'feature/attributes'
[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-09 19:24:28 CET by Kim Nguyen>
19 *)
20
21   open Ast
22   let f () = ()
23 %}
24
25 %token <string> TAG
26 %token <string> STRING
27 %token <int>  INT
28 %token <float> FLOAT
29 %token <Ast.axis> AXIS
30 %token RB LB LP RP
31 %token SLASH SLASHSLASH COLONCOLON STAR PIPE
32 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
33 %token NODE TEXT
34 %token COMMA
35 %token EOF
36
37 %left OR
38 %left AND
39 %left EQ NEQ
40 %left LT GT LTE GTE
41 %left ADD SUB
42 %left MOD DIV STAR
43 %nonassoc uminus
44
45 %start xpath_query
46 %type <Ast.path> xpath_query
47
48
49 %%
50 xpath_query:
51 path EOF          { $1 }
52 ;
53
54 path:
55   path_rev { List.rev $1 }
56 ;
57
58 path_rev:
59   simple_path     { [ $1 ] }
60 | path_rev PIPE simple_path { $3 :: $1 }
61 ;
62
63
64 simple_path:
65    absolute_path  { Absolute  (List.rev $1) }
66 |  relative_path  { Relative  (List.rev $1) }
67 ;
68
69 absolute_path:
70   SLASH relative_path { $2 }
71 | SLASHSLASH relative_path { $2 @ [(Descendant true, node, [])] }
72 ;
73
74 relative_path:
75   step { [ $1 ] }
76 | relative_path SLASH step { $3 :: $1 }
77 | relative_path SLASHSLASH step { $3
78                                   :: (Descendant true, node, [])
79                                   :: $1 }
80 ;
81
82 step:
83   axis_test pred_list    { let a, b = $1 in a, b, $2 }
84 ;
85
86 axis_test:
87   AXIS COLONCOLON test  { let a, t = $1, $3 in
88                           if a == Attribute && Utils.QNameSet.is_finite t then 
89                             (a, Utils.QNameSet.fold
90                               (fun t a ->
91                                 Utils.QNameSet.add
92                                   (Utils.QName.add_attribute_prefix t) a)
93                               t Utils.QNameSet.empty)
94                           else
95                             (a, t)
96                         }
97 | test                  { Child, $1 }
98 | AXIS            {
99   let _ = Format.flush_str_formatter () in
100   let () = Format.fprintf Format.str_formatter "%a" Ast.print_axis $1 in
101   let a = Format.flush_str_formatter () in
102   Child, Utils.QNameSet.singleton (Utils.QName.of_string a)
103 }
104 ;
105
106 test:
107   NODE                { node }
108 | TEXT                { text }
109 | STAR                { star }
110 | TAG                 { Utils.QNameSet.singleton(Utils.QName.of_string $1) }
111 ;
112
113 pred_list:
114   pred_list_rev             { List.rev $1 }
115 ;
116
117 pred_list_rev:
118              { [] }
119 | pred_list LB expr RB   { $3 :: $1 }
120 ;
121
122 expr:
123   INT                       { Number(`Int($1)) }
124 | FLOAT                     { Number(`Float($1)) }
125 | STRING                    { String $1 }
126 | SUB expr     %prec uminus { Unop(Neg, $2) }
127 | expr AND expr             { Binop($1, And, $3) }
128 | expr OR expr              { Binop($1, Or, $3) }
129 | expr ADD expr             { Binop($1, Add, $3) }
130 | expr SUB expr             { Binop($1, Sub, $3) }
131 | expr STAR expr            { Binop($1, Mult, $3) }
132 | expr DIV expr             { Binop($1, Div, $3) }
133 | expr MOD expr             { Binop($1, Mod, $3) }
134 | expr EQ expr              { Binop($1, Eq, $3) }
135 | expr NEQ expr             { Binop($1, Neq, $3) }
136 | expr LT expr              { Binop($1, Lt, $3) }
137 | expr LTE expr             { Binop($1, Lte, $3) }
138 | expr GT expr              { Binop($1, Gt, $3) }
139 | expr GTE expr             { Binop($1, Gte, $3) }
140 | TAG LP arg_list RP        { Fun_call(Utils.QName.of_string $1, $3) }
141 | LP expr RP                { $2 }
142 | path                      { Path $1 }
143 ;
144
145 arg_list:
146                             { [] }
147 | arg_list1                 { List.rev $1 }
148 ;
149
150 arg_list1:
151   expr                     { [ $1 ] }
152 | arg_list1 COMMA expr     { $3 :: $1 }
153 ;
154