**** Merged from MCS ****
[mono-project.git] / mcs / class / System.XML / System.Xml.XPath / Parser.jay
blob6dd4fa8ac14bed74195303605a1d71fca87809a3
1 %{
2 // XPath parser
3 //
4 // Author - Piers Haken <piersh@friskit.com>
5 //
7 using System;
8 using System.Xml;
9 using System.Xml.XPath;
11 namespace Mono.Xml.XPath
13         internal class XPathParser
14         {
15         
16                 internal System.Xml.Xsl.IStaticXsltContext Context;
17                 
18                 public XPathParser () : this (null) {}
19                 internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
20                 {
21                         Context = context;
22                         ErrorOutput = System.IO.TextWriter.Null;
23                 }
24                 
25                 internal Expression Compile (string xpath)
26                 {
27                         try {
28                                 Tokenizer tokenizer = new Tokenizer (xpath);
29                                 return (Expression) yyparse (tokenizer);
30                         } catch (XPathException e) {
31                                 throw e;
32                         } catch (Exception e) {
33                                 throw new XPathException ("Error during parse of " + xpath, e);
34                         }
35                 }
38 %token ERROR
39 %token EOF
41 %token SLASH                    "/"
42 %token SLASH2                   "//"
43 %token DOT                              "."
44 %token DOT2                             ".."
45 %token COLON2                   "::"
46 %token COMMA                    ","
47 %token AT                               "@"
49 %token FUNCTION_NAME
51 %token BRACKET_OPEN             "["
52 %token BRACKET_CLOSE    "]"
53 %token PAREN_OPEN               "("
54 %token PAREN_CLOSE              ")"
56 %token AND                              "and"
57 %token OR                               "or"
58 %token DIV                              "div"
59 %token MOD                              "mod"
60 %token PLUS                             "+"
61 %token MINUS                    "-"
62 %token ASTERISK                 "*"
63 %token DOLLAR                   "$"
64 %token BAR                              "|"
65 %token EQ                               "="
66 %token NE                               "!="
67 %token LE                               "<="
68 %token GE                               ">="
69 %token LT                               "<"
70 %token GT                               ">"
72 %token ANCESTOR                                 "ancestor"
73 %token ANCESTOR_OR_SELF                 "ancstor-or-self"
74 %token ATTRIBUTE                                "attribute"
75 %token CHILD                                    "child"
76 %token DESCENDANT                               "descendant"
77 %token DESCENDANT_OR_SELF               "descendant-or-self"
78 %token FOLLOWING                                "following"
79 %token FOLLOWING_SIBLING                "sibling"
80 %token NAMESPACE                                "NameSpace"
81 %token PARENT                                   "parent"
82 %token PRECEDING                                "preceding"
83 %token PRECEDING_SIBLING                "preceding-sibling"
84 %token SELF                                             "self"
86 %token COMMENT                                  "comment"
87 %token TEXT                                             "text"
88 %token PROCESSING_INSTRUCTION   "processing-instruction"
89 %token NODE                                             "node"
91 %token MULTIPLY                 "*"
93 %token NUMBER
94 %token LITERAL
95 %token QName
98 %start Expr
101 %left AND
102 %left OR
103 %left EQ
104 %left NE
105 %left LE
106 %left GE
107 %left LT
108 %left GT
110 %left DIV
111 %left MOD
112 %left PLUS
113 %left MINUS
118 Expr
119         : OrExpr
120         ;
121         
122 OrExpr
123         : AndExpr 
124         | OrExpr OR AndExpr
125         {
126                 $$ = new ExprOR ((Expression) $1, (Expression) $3);
127         }
128         ;
130 AndExpr
131         : EqualityExpr 
132         | AndExpr AND EqualityExpr 
133         {
134                 $$ = new ExprAND ((Expression) $1, (Expression) $3);
135         }
136         ;
138 EqualityExpr
139         : RelationalExpr 
140         | EqualityExpr EQ RelationalExpr 
141         {
142                 $$ = new ExprEQ ((Expression) $1, (Expression) $3);
143         }
144         | EqualityExpr NE RelationalExpr 
145         {
146                 $$ = new ExprNE ((Expression) $1, (Expression) $3);
147         }
148         ;
150 RelationalExpr
151         : AdditiveExpr 
152         | RelationalExpr LT AdditiveExpr 
153         {
154                 $$ = new ExprLT ((Expression) $1, (Expression) $3);
155         }
156         | RelationalExpr GT AdditiveExpr 
157         {
158                 $$ = new ExprGT ((Expression) $1, (Expression) $3);
159         }
160         | RelationalExpr LE AdditiveExpr 
161         {
162                 $$ = new ExprLE ((Expression) $1, (Expression) $3);
163         }
164         | RelationalExpr GE AdditiveExpr 
165         {
166                 $$ = new ExprGE ((Expression) $1, (Expression) $3);
167         }
168         ;
170 AdditiveExpr
171         : MultiplicativeExpr 
172         | AdditiveExpr PLUS MultiplicativeExpr
173         {
174                 $$ = new ExprPLUS ((Expression) $1, (Expression) $3);
175         }
176         | AdditiveExpr MINUS MultiplicativeExpr
177         {
178                 $$ = new ExprMINUS ((Expression) $1, (Expression) $3);
179         }
180         ;
182 MultiplicativeExpr
183         : UnaryExpr 
184         | MultiplicativeExpr MULTIPLY UnaryExpr 
185         {
186                 $$ = new ExprMULT ((Expression) $1, (Expression) $3);
187         }
188         | MultiplicativeExpr DIV UnaryExpr
189         {
190                 $$ = new ExprDIV ((Expression) $1, (Expression) $3);
191         }
192         | MultiplicativeExpr MOD UnaryExpr
193         {
194                 $$ = new ExprMOD ((Expression) $1, (Expression) $3);
195         }
196         ;
198 UnaryExpr
199         : UnionExpr 
200         | MINUS UnaryExpr 
201         {
202                 $$ = new ExprNEG ((Expression) $2);
203         }
204         ;
206 UnionExpr
207         : PathExpr 
208         | UnionExpr BAR PathExpr
209         {
210                 $$ = new ExprUNION ((Expression) $1, (Expression) $3);
211         }
212         ;
214 PathExpr
215         : LocationPath
216         | FilterExpr
217         | FilterExpr SLASH RelativeLocationPath
218         {
219                 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
220         }
221         | FilterExpr SLASH2 RelativeLocationPath
222         {
223                 $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
224         }
225         ;
227 LocationPath
228         : RelativeLocationPath
229         | AbsoluteLocationPath
230         ;
232 AbsoluteLocationPath
233         : SLASH
234         {
235                 $$ = new ExprRoot ();
236         }
237         | SLASH RelativeLocationPath
238         {
239                 $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
240         }
241         | SLASH2 RelativeLocationPath
242         {
243                 $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
244         }
245         ;
247 RelativeLocationPath
248         : Step
249         | RelativeLocationPath SLASH Step 
250         {
251                 $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3);
252         }
253         | RelativeLocationPath SLASH2 Step 
254         {
255                 $$ = new ExprSLASH2 ((NodeSet) $1, (NodeSet) $3);
256         }
257         ;
259 Step
260         : PredicatedStep
261         | DOT
262         {
263                 $$ = new NodeTypeTest (Axes.Self, XPathNodeType.All);
264         }
265         | DOT2
266         {
267                 $$ = new NodeTypeTest (Axes.Parent, XPathNodeType.All);
268         }
269         ;
271 PredicatedStep
272         : AxisTest
273         | PredicatedStep Predicate
274         {
275                 $$ = new ExprFilter ((NodeSet) $1, (Expression) $2);
276         }
277         ;
279 AxisTest
280         : AxisSpecifier QName
281         {
282                 $$ = new NodeNameTest ((Axes) $1, (XmlQualifiedName) $2, Context);
283         }
284         | AxisSpecifier ASTERISK
285         {
286                 $$ = new NodeTypeTest ((Axes) $1);
287         }
288         | AxisSpecifier NodeType PAREN_OPEN OptionalLiteral PAREN_CLOSE
289         {
290                 $$ = new NodeTypeTest ((Axes) $1, (XPathNodeType) $2, (String) $4);
291         }
292         ;
294 AxisSpecifier
295         : /* empty */
296         {
297                 $$ = Axes.Child;
298         }
299         | AT
300         {
301                 $$ = Axes.Attribute;
302         }
303         | AxisName COLON2
304         {
305                 $$ = $1;
306         }
307         ;
309 NodeType
310         : COMMENT                                       { $$ = XPathNodeType.Comment; }
311         | TEXT                                          { $$ = XPathNodeType.Text; }
312         | PROCESSING_INSTRUCTION        { $$ = XPathNodeType.ProcessingInstruction; }
313         | NODE                                          { $$ = XPathNodeType.All; }
314         ;
317 FilterExpr
318         : PrimaryExpr 
319         | FilterExpr Predicate 
320         {
321                 $$ = new ExprFilter ((Expression) $1, (Expression) $2);
322         }
323         ;
325 PrimaryExpr
326         : DOLLAR QName
327         {
328                 Expression ret = null;
329                 if (Context != null)
330                         ret = Context.TryGetVariable (((XmlQualifiedName) $2).ToString ());
331                 
332                 if (ret == null)
333                         ret = new ExprVariable ((XmlQualifiedName) $2, Context);
334                         
335                 $$ = ret;
336         }
337         | PAREN_OPEN Expr PAREN_CLOSE
338         {
339                 $$ = new ExprParens ((Expression) $2);
340         }
341         | LITERAL
342         {
343                 $$ = new ExprLiteral ((String) $1);
344         }
345         | NUMBER
346         {
347                 $$ = new ExprNumber ((double) $1);
348         }
349         | FunctionCall
350         ;
352 FunctionCall
353         : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE
354         {
355                 Expression ret = null;
356                 if (Context != null)
357                         ret = Context.TryGetFunction ((XmlQualifiedName) $1, (FunctionArguments) $3);
358                 if (ret == null)
359                         ret = ExprFunctionCall.Factory ((XmlQualifiedName) $1, (FunctionArguments) $3, Context);
360                 
361                 $$ = ret;
362         }
363         ;
365 OptionalArgumentList
366         : /* empty */
367         | Expr OptionalArgumentListTail
368         {
369                 $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2);
370         }
371         ;
373 OptionalArgumentListTail
374         : /* empty */
375         | COMMA Expr OptionalArgumentListTail
376         {
377                 $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3);
378         }
379         ;
381 Predicate
382         : BRACKET_OPEN Expr BRACKET_CLOSE
383         {
384                 $$ = $2;
385         }
386         ;
388 AxisName
389         : ANCESTOR                              { $$ = Axes.Ancestor; }
390         | ANCESTOR_OR_SELF              { $$ = Axes.AncestorOrSelf; }
391         | ATTRIBUTE                             { $$ = Axes.Attribute; }
392         | CHILD                                 { $$ = Axes.Child; }
393         | DESCENDANT                    { $$ = Axes.Descendant; }
394         | DESCENDANT_OR_SELF    { $$ = Axes.DescendantOrSelf; }
395         | FOLLOWING                             { $$ = Axes.Following; }
396         | FOLLOWING_SIBLING             { $$ = Axes.FollowingSibling; }
397         | NAMESPACE                             { $$ = Axes.Namespace; }
398         | PARENT                                { $$ = Axes.Parent; }
399         | PRECEDING                             { $$ = Axes.Preceding; }
400         | PRECEDING_SIBLING             { $$ = Axes.PrecedingSibling; }
401         | SELF                                  { $$ = Axes.Self; }
402         ;
404 OptionalLiteral
405         : /* empty */
406         | LITERAL
407         ;
410         }