Initial public import
[afterthought.git] / aft_parser.mly
1 %{
2   open Xpath_syntax
3   open Xpath_ext
4   open Axis
5   open Aft_types
6 %}
7
8 %token POINT LBRACE RBRACE
9 %token SLASH LPAREN RPAREN LBRACKET RBRACKET
10 %token DOUBLESLASH DOUBLEDOT AT DOT COMMA PIPE
11 %token OR AND EQUAL NOTEQUAL LT GT LTE GTE
12 %token PLUS MINUS MUL DIV MOD
13 %token <string> VAR
14 %token <string> NAME_TEST AXIS FUNCTION_NAME NODE_TYPE
15 %token <string> LITERAL
16 %token <float> NUMBER
17 %token EOF
18
19 %type <Aft_types.pattern_match> aft_pattern_match
20 %start aft_pattern_match
21
22 %type <Aft_types.access_spec> access_spec
23 %start access_spec
24
25 %%
26 access_spec:
27     expr { Filter($1) }
28  |  aft_pattern_match { PatternMatch($1) }
29
30 aft_clause:
31     location_path POINT LBRACE access_spec RBRACE { Clause($1 , $4) }
32
33 aft_pattern_match:
34     aft_clause { [ $1 ] }
35  |  aft_clause PIPE aft_pattern_match {$1::$3}
36
37 location_path:
38    relative_location_path      { $1 }
39  | absolute_location_path      { $1 }
40
41 absolute_location_path:
42    SLASH   { Root }
43  | SLASH relative_location_path  { Slash (Root,$2) }
44  | DOUBLESLASH relative_location_path { double_slash Root $2 }
45
46 relative_location_path:
47    step    { $1 }
48  | relative_location_path SLASH step { Slash ($1,$3) }
49  | relative_location_path DOUBLESLASH step { double_slash $1 $3 }
50
51 step:
52  | axis_specifier step2 { Axis ($1,$2) }
53  | step2 { $1 }
54  | DOT   { dot  }
55  | DOUBLEDOT  { dotdot }
56
57 step2:
58  | step2 LBRACKET expr RBRACKET { Condition ($1,$3) } 
59  | node_test { $1 } 
60
61 axis_specifier:
62  | AXIS { 
63      try Axis.of_string $1 
64      with Not_found -> failwith ("Unknown axis :"^$1)
65    }
66  | AT { Axis.Attribute }
67
68
69 node_test:
70  | NAME_TEST  { Name $1 }
71  | NODE_TYPE RPAREN { 
72      try TypeTest (Type_test.of_string $1) 
73      with Not_found -> failwith ("Unknown node type :"^$1)
74    }
75  | NODE_TYPE LITERAL RPAREN {
76      match $1 with
77        | "processing-instruction" ->
78            TypeTest (Type_test.Pi_test (Some $2))
79        | _ -> failwith "Only processing-instruction tests accept argument" 
80    }
81
82 primary_expr:
83    function_call   { $1 }
84  | VAR             { Var $1 }
85  | LPAREN expr RPAREN  { $2 }
86  | LITERAL         { String_literal $1 } 
87  | NUMBER          { Number_literal $1 } 
88
89 function_call:
90    FUNCTION_NAME RPAREN  { Function ($1,[]) }
91  | FUNCTION_NAME arguments RPAREN  { Function ($1,$2) }
92
93 arguments:
94    arguments COMMA expr   { $1@[$3] }
95  | expr { [$1] }
96
97 union_expr:
98    path_expr        { $1 }
99  | union_expr PIPE path_expr  { path_expr (Pipe(expr $1, expr $3)) }
100
101 path_expr:
102    location_path    { path_expr $1 }
103  | filter_expr      { $1 } 
104  | filter_expr SLASH relative_location_path 
105      {  path_expr (Slash (expr $1,$3)) } 
106  | filter_expr DOUBLESLASH relative_location_path 
107      {  path_expr (double_slash (expr $1) $3) }
108
109  
110 filter_expr:
111    primary_expr { $1 }  
112  | filter_expr LBRACKET expr RBRACKET { path_expr (Condition (expr $1,$3)) } 
113
114
115 expr:
116    or_expr         { $1 } 
117
118 or_expr:
119    and_expr        { $1 } 
120  | or_expr OR and_expr { Or($1,$3) }
121
122 and_expr:
123    equality_expr   { $1 }
124  | and_expr AND equality_expr { And($1,$3) }
125
126 equality_expr:
127    relational_expr  { $1 }
128  | equality_expr EQUAL relational_expr { Equal($1,$3) }
129  | equality_expr NOTEQUAL relational_expr { NotEqual($1,$3) }
130
131 relational_expr: 
132    additive_expr    { $1 }
133  | relational_expr LT additive_expr { Lower($1,$3) }
134  | relational_expr GT additive_expr { Greater($1,$3) }
135  | relational_expr LTE additive_expr { LowerEqual($1,$3) }
136  | relational_expr GTE additive_expr { GreaterEqual($1,$3) }
137
138 additive_expr:
139    multiplicative_expr  { $1 }
140  | additive_expr PLUS multiplicative_expr  { Plus($1,$3) }
141  | additive_expr MINUS multiplicative_expr  { Minus($1,$3) }
142
143 multiplicative_expr:
144    unary_expr  { $1 }
145  | multiplicative_expr MUL unary_expr  { Mul ($1,$3) }
146  | multiplicative_expr DIV unary_expr  { Div ($1,$3) }
147  | multiplicative_expr MOD unary_expr  { Mod ($1,$3) }
148
149 unary_expr:
150  | union_expr  { $1 }
151  | MINUS unary_expr { UnaryMinus $2 }