2002-09-21 Piers Haken <piersh@friskit.com>
[mono.git] / mcs / class / System.XML / System.Xml.XPath / Parser.jay
1 %{
2 // XPath parser
3 //
4 // Author - Piers Haken <piersh@friskit.com>
5 //
6
7 // TODO: FUNCTION_CALL should be a QName, not just a NCName
8 // TODO: PROCESSING_INSTRUCTION's optional parameter
9 // TODO: flatten argument/predicate lists in place
10
11 using System;
12 using System.Xml.XPath;
13 using Test.Xml.XPath;
14
15 namespace Mono.Xml.XPath
16 {
17         public class XPathParser
18         {
19                 internal object yyparseSafe (Tokenizer tok)
20                 {
21                         return yyparseSafe (tok, null);
22                 }
23
24                 internal object yyparseSafe (Tokenizer tok, object yyDebug)
25                 {
26                         try
27                         {
28                                 return yyparse (tok, yyDebug);
29                         }
30                         catch (XPathException e)
31                         {
32                                 throw e;
33                         }
34                         catch (Exception e)
35                         {
36                                 throw new XPathException ("Error during parse", e);
37                         }
38                 }
39
40                 internal object yyparseDebug (Tokenizer tok)
41                 {
42                         return yyparseSafe (tok, new yydebug.yyDebugSimple ());
43                 }
44
45 %}
46
47 %token ERROR
48 %token EOF
49
50 %token SLASH
51 %token SLASH2
52 %token DOT
53 %token DOT2
54 %token COLON
55 %token COLON2
56 %token COMMA
57 %token AT
58
59 %token FUNCTION_NAME
60
61 %token BRACKET_OPEN
62 %token BRACKET_CLOSE
63 %token PAREN_OPEN
64 %token PAREN_CLOSE
65
66 %token AND
67 %token OR
68 %token DIV
69 %token MOD
70 %token PLUS
71 %token MINUS
72 %token ASTERISK
73 %token DOLLAR
74 %token BAR
75 %token EQ
76 %token NE
77 %token LE
78 %token GE
79 %token LT
80 %token GT
81
82 %token ANCESTOR
83 %token ANCESTOR_OR_SELF
84 %token ATTRIBUTE
85 %token CHILD
86 %token DESCENDANT
87 %token DESCENDANT_OR_SELF
88 %token FOLLOWING
89 %token FOLLOWING_SIBLING
90 %token NAMESPACE
91 %token PARENT
92 %token PRECEDING
93 %token PRECEDING_SIBLING
94 %token SELF
95
96 %token COMMENT
97 %token TEXT
98 %token PROCESSING_INSTRUCTION
99 %token NODE
100
101 %token NUMBER
102 %token LITERAL
103 %token NCName
104
105
106 %start Expr
107
108
109 %left AND
110 %left OR
111 %left EQ
112 %left NE
113 %left LE
114 %left GE
115 %left LT
116 %left GT
117
118 %left DIV
119 %left MOD
120 %left PLUS
121 %left MINUS
122
123 %%
124
125
126 Expr
127         : OrExpr
128         ;
129         
130 OrExpr
131         : AndExpr 
132         | OrExpr OR AndExpr
133         {
134                 $$ = new ExprOR ((Expression) $1, (Expression) $3);
135         }
136         ;
137
138 AndExpr
139         : EqualityExpr 
140         | AndExpr AND EqualityExpr 
141         {
142                 $$ = new ExprAND ((Expression) $1, (Expression) $3);
143         }
144         ;
145
146 EqualityExpr
147         : RelationalExpr 
148         | EqualityExpr EQ RelationalExpr 
149         {
150                 $$ = new ExprEQ ((Expression) $1, (Expression) $3);
151         }
152         | EqualityExpr NE RelationalExpr 
153         {
154                 $$ = new ExprNE ((Expression) $1, (Expression) $3);
155         }
156         ;
157
158 RelationalExpr
159         : AdditiveExpr 
160         | RelationalExpr LT AdditiveExpr 
161         {
162                 $$ = new ExprLT ((Expression) $1, (Expression) $3);
163         }
164         | RelationalExpr GT AdditiveExpr 
165         {
166                 $$ = new ExprGT ((Expression) $1, (Expression) $3);
167         }
168         | RelationalExpr LE AdditiveExpr 
169         {
170                 $$ = new ExprLE ((Expression) $1, (Expression) $3);
171         }
172         | RelationalExpr GE AdditiveExpr 
173         {
174                 $$ = new ExprGE ((Expression) $1, (Expression) $3);
175         }
176         ;
177
178 AdditiveExpr
179         : MultiplicativeExpr 
180         | AdditiveExpr PLUS MultiplicativeExpr
181         {
182                 $$ = new ExprPLUS ((Expression) $1, (Expression) $3);
183         }
184         | AdditiveExpr MINUS MultiplicativeExpr
185         {
186                 $$ = new ExprMINUS ((Expression) $1, (Expression) $3);
187         }
188         ;
189
190 MultiplicativeExpr
191         : UnaryExpr 
192         | MultiplicativeExpr ASTERISK UnaryExpr 
193         {
194                 $$ = new ExprMULT ((Expression) $1, (Expression) $3);
195         }
196         | MultiplicativeExpr DIV UnaryExpr
197         {
198                 $$ = new ExprDIV ((Expression) $1, (Expression) $3);
199         }
200         | MultiplicativeExpr MOD UnaryExpr
201         {
202                 $$ = new ExprMOD ((Expression) $1, (Expression) $3);
203         }
204         ;
205
206 UnaryExpr
207         : UnionExpr 
208         | MINUS UnaryExpr 
209         {
210                 $$ = new ExprNEG ((Expression) $2);
211         }
212         ;
213
214 UnionExpr
215         : PathExpr 
216         | UnionExpr BAR PathExpr
217         {
218                 $$ = new ExprUNION ((NodeSet) $1, (NodeSet) $3);
219         }
220         ;
221
222 PathExpr
223         : RelativeLocationPath
224         | SLASH
225         {
226                 $$ = new ExprRoot ();
227         }
228         | SLASH RelativeLocationPath
229         {
230                 $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
231         }
232         | SLASH2 RelativeLocationPath 
233         {
234                 ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, XPathNodeType.All));
235                 $$ = new ExprSLASH (new ExprSLASH (new ExprRoot (), exprStep), (NodeSet) $2);
236         }
237         | FilterExpr 
238         | FilterExpr SLASH RelativeLocationPath
239         {
240                 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
241         }
242         | FilterExpr SLASH2 RelativeLocationPath
243         {
244                 ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, XPathNodeType.All));
245                 $$ = new ExprSLASH (new ExprSLASH ((Expression) $1, exprStep), (NodeSet) $3);
246         }
247         ;
248
249 RelativeLocationPath
250         : Step
251         | RelativeLocationPath SLASH Step 
252         {
253                 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
254         }
255         | RelativeLocationPath SLASH2 Step 
256         {
257                 ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, XPathNodeType.All));
258                 $$ = new ExprSLASH (new ExprSLASH ((Expression) $1, exprStep), (NodeSet) $3);
259         }
260         ;
261
262 Step
263         : AxisSpecifier QName ZeroOrMorePredicates
264         {
265                 $$ = new ExprStep (new NodeNameTest ((Axes) $1, (QName) $2), (ExprPredicates) $3);
266         }
267         | AxisSpecifier ASTERISK ZeroOrMorePredicates
268         {
269                 $$ = new ExprStep (new NodeTypeTest ((Axes) $1), (ExprPredicates) $3);
270         }
271         | AxisSpecifier NodeType PAREN_OPEN OptionalLiteral PAREN_CLOSE ZeroOrMorePredicates
272         {
273                 $$ = new ExprStep (new NodeTypeTest ((Axes) $1, (XPathNodeType) $2, (String) $4), (ExprPredicates) $6);
274         }
275         | DOT
276         {
277                 $$ = new ExprStep (new NodeTypeTest (Axes.Self, XPathNodeType.All));
278         }
279         | DOT2
280         {
281                 $$ = new ExprStep (new NodeTypeTest (Axes.Parent, XPathNodeType.All));
282         }
283         ;
284
285 AxisSpecifier
286         : /* empty */
287         {
288                 $$ = Axes.Child;
289         }
290         | AT
291         {
292                 $$ = Axes.Attribute;
293         }
294         | AxisName COLON2
295         {
296                 $$ = $1;
297         }
298         ;
299
300 NodeType
301         : COMMENT                                       { $$ = XPathNodeType.Comment; }
302         | TEXT                                          { $$ = XPathNodeType.Text; }
303         | PROCESSING_INSTRUCTION        { $$ = XPathNodeType.ProcessingInstruction; }
304         | NODE                                          { $$ = XPathNodeType.All; }
305         ;
306
307
308 FilterExpr
309         : PrimaryExpr 
310         | FilterExpr Predicate 
311         {
312                 $$ = new ExprFilter ((Expression) $1, (Expression) $2);
313         }
314         ;
315
316 PrimaryExpr
317         : DOLLAR QName
318         {
319                 $$ = new ExprVariable ((QName) $2);
320         } 
321         | PAREN_OPEN Expr PAREN_CLOSE
322         {
323                 $$ = $2;
324         }
325         | LITERAL
326         {
327                 $$ = new ExprLiteral ((String) $1);
328         }
329         | NUMBER
330         {
331                 $$ = new ExprNumber ((double) $1);
332         }
333         | FunctionCall
334         ;
335
336 FunctionCall
337         : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE
338         {
339                 $$ = new ExprFunctionCall ((String) $1, (FunctionArguments) $3);
340         }
341         ;
342
343 OptionalArgumentList
344         : /* empty */
345         | Expr OptionalArgumentListTail
346         {
347                 $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2);
348         }
349         ;
350
351 OptionalArgumentListTail
352         : /* empty */
353         | COMMA Expr OptionalArgumentListTail
354         {
355                 $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3);
356         }
357         ;
358
359
360 ZeroOrMorePredicates
361         : /* empty */
362         | Predicate ZeroOrMorePredicates
363         {
364                 $$ = new ExprPredicates ((Expression) $1, (ExprPredicates) $2);
365         }
366         ;
367
368 Predicate
369         : BRACKET_OPEN Expr BRACKET_CLOSE
370         {
371                 $$ = $2;
372         }
373         ;
374
375 AxisName
376         : ANCESTOR                              { $$ = Axes.Ancestor; }
377         | ANCESTOR_OR_SELF              { $$ = Axes.AncestorOrSelf; }
378         | ATTRIBUTE                             { $$ = Axes.Attribute; }
379         | CHILD                                 { $$ = Axes.Child; }
380         | DESCENDANT                    { $$ = Axes.Descendant; }
381         | DESCENDANT_OR_SELF    { $$ = Axes.DescendantOrSelf; }
382         | FOLLOWING                             { $$ = Axes.Following; }
383         | FOLLOWING_SIBLING             { $$ = Axes.FollowingSibling; }
384         | NAMESPACE                             { $$ = Axes.Namespace; }
385         | PARENT                                { $$ = Axes.Parent; }
386         | PRECEDING                             { $$ = Axes.Preceding; }
387         | PRECEDING_SIBLING             { $$ = Axes.PrecedingSibling; }
388         | SELF                                  { $$ = Axes.Self; }
389         ;
390
391 OptionalLiteral
392         : /* empty */
393         | LITERAL
394         ;
395
396 QName
397         : NCName
398         {
399                 $$ = new NCName ((String) $1);
400         }
401         | NCName COLON ASTERISK
402         {
403                 $$ = new QName ((String) $1, null);
404         }
405         | NCName COLON NCName
406         {
407                 $$ = new QName ((String) $1, (String) $3);
408         }
409         ;
410
411 %%
412         }