39b2187a31d75ad0b84cc2b57ac1946963882a0b
[tatoo.git] / src / parser.mly
1 %{
2
3   open XPath.Ast
4   let f () = ()
5 %}
6
7 %token <string> TAG
8 %token <string> STRING
9 %token <int>  INT
10 %token <float> FLOAT
11 %token <XPath.Ast.axis> AXIS
12 %token RB LB LP RP
13 %token SLASH SLASHSLASH COLONCOLON STAR PIPE
14 %token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
15 %token NODE TEXT
16 %token COMMA
17 %token EOF
18
19 %left OR
20 %left AND
21 %left EQ NEQ
22 %left LT GT LTE GTE
23 %left ADD SUB
24 %left MOD DIV STAR
25 %nonassoc uminus
26
27 %start xpath
28 %type <XPath.Ast.path> xpath
29
30
31 %%
32 xpath:
33 path EOF          { $1 }
34 ;
35
36 path:
37   path_rev { List.rev $1 }
38 ;
39
40 path_rev:
41   simple_path     { [ $1 ] }
42 | path_rev PIPE simple_path { $3 :: $1 }
43 ;
44
45
46 simple_path:
47    absolute_path  { Absolute  (List.rev $1) }
48 |  relative_path  { Relative  (List.rev $1) }
49 ;
50
51 absolute_path:
52   SLASH relative_path { $2 }
53 | SLASHSLASH relative_path { (DescendantOrSelf, node, []) :: $2 }
54 ;
55
56 relative_path:
57   step { [ $1 ] }
58 | relative_path SLASH step { $3 :: $1 }
59 | relative_path SLASHSLASH step { $3
60                                   :: (DescendantOrSelf, node, [])
61                                   :: $1 }
62 ;
63
64 step:
65   axis_test pred_list    { let a, b = $1 in a, b, $2 }
66 ;
67
68 axis_test:
69   AXIS COLONCOLON test  { $1, $3 }
70 | test                  { Child, $1 }
71 | AXIS            {
72   let _ = Format.flush_str_formatter () in
73   let () = Format.fprintf Format.str_formatter "%a" XPath.Ast.print_axis $1 in
74   let a = Format.flush_str_formatter () in
75   Child, QNameSet.singleton (QName.of_string a)
76 }
77 ;
78
79 test:
80   NODE                { node }
81 | TEXT                { text }
82 | STAR                { star }
83 | TAG                 { QNameSet.singleton(QName.of_string $1) }
84 ;
85
86 pred_list:
87   pred_list_rev             { List.rev $1 }
88 ;
89
90 pred_list_rev:
91              { [] }
92 | pred_list LB expr RB   { $3 :: $1 }
93 ;
94
95 expr:
96   INT                       { Number(`Int($1)) }
97 | FLOAT                     { Number(`Float($1)) }
98 | STRING                    { String $1 }
99 | SUB expr     %prec uminus { Unop(Neg, $2) }
100 | expr AND expr             { Binop($1, And, $3) }
101 | expr OR expr              { Binop($1, Or, $3) }
102 | expr ADD expr             { Binop($1, Add, $3) }
103 | expr SUB expr             { Binop($1, Sub, $3) }
104 | expr STAR expr            { Binop($1, Mult, $3) }
105 | expr DIV expr             { Binop($1, Div, $3) }
106 | expr MOD expr             { Binop($1, Mod, $3) }
107 | expr EQ expr              { Binop($1, Eq, $3) }
108 | expr NEQ expr             { Binop($1, Neq, $3) }
109 | expr LT expr              { Binop($1, Lt, $3) }
110 | expr LTE expr             { Binop($1, Lte, $3) }
111 | expr GT expr              { Binop($1, Gt, $3) }
112 | expr GTE expr             { Binop($1, Gte, $3) }
113 | TAG LP arg_list RP        { Fun_call(QName.of_string $1, $3) }
114 | LP expr RP                { $2 }
115 | path                      { Path $1 }
116 ;
117
118 arg_list:
119                             { [] }
120 | arg_list1                 { List.rev $1 }
121 ;
122
123 arg_list1:
124   expr                     { [ $1 ] }
125 | arg_list1 COMMA expr     { $3 :: $1 }
126 ;
127