1
2
3
4
5
6 using XPathTokens;
7
8 parser XPathParser
9 {
10 uselexer XPathLexer;
11 main;
12
13 Expr : System.XPath.XPathExpr*
14 ::= OrExpr:orExpr{ return orExpr; }
15 ;
16
17 OrExpr(var UniquePtr<System.XPath.XPathExpr> expr) : System.XPath.XPathExpr*
18 ::= (AndExpr:left{ expr.Reset(left); } (NAME{ Token token = lexer.GetToken(pos); pass = lexer.GetKeywordToken(token.match) == OR; } AndExpr:right{ expr.Reset(new System.XPath.XPathOrExpr(expr.Release(), right)); })*)
19 {
20 return expr.Release();
21 }
22 ;
23
24 AndExpr(var UniquePtr<System.XPath.XPathExpr> expr) : System.XPath.XPathExpr*
25 ::= (EqualityExpr:left{ expr.Reset(left); } (NAME{ Token token = lexer.GetToken(pos); pass = lexer.GetKeywordToken(token.match) == AND; } EqualityExpr:right{ expr.Reset(new System.XPath.XPathAndExpr(expr.Release(), right)); })*)
26 {
27 return expr.Release();
28 }
29 ;
30
31 EqualityExpr(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
32 ::=
33 ( RelationalExpr:left{ expr.Reset(left); }
34 ( (EQ{ op = System.XPath.Operator.equal; } | NEQ{ op = System.XPath.Operator.notEqual; })
35 RelationalExpr:right!
36 {
37 switch (op)
38 {
39 case System.XPath.Operator.equal: expr.Reset(new System.XPath.XPathEqualExpr(expr.Release(), right)); break;
40 case System.XPath.Operator.notEqual: expr.Reset(new System.XPath.XPathNotEqualExpr(expr.Release(), right)); break;
41 }
42 }
43 )*
44 )
45 {
46 return expr.Release();
47 }
48 ;
49
50 RelationalExpr(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
51 ::=
52 ( AdditiveExpr:left{ expr.Reset(left); }
53 ( (LEQ{ op = System.XPath.Operator.lessOrEqual; } | GEQ{ op = System.XPath.Operator.greaterOrEqual; } | LESS{ op = System.XPath.Operator.less; } | GREATER{ op = System.XPath.Operator.greater; })
54 AdditiveExpr:right!
55 {
56 switch (op)
57 {
58 case System.XPath.Operator.lessOrEqual: expr.Reset(new System.XPath.XPathLessOrEqualExpr(expr.Release(), right)); break;
59 case System.XPath.Operator.greaterOrEqual: expr.Reset(new System.XPath.XPathGreaterOrEqualExpr(expr.Release(), right)); break;
60 case System.XPath.Operator.less: expr.Reset(new System.XPath.XPathLessExpr(expr.Release(), right)); break;
61 case System.XPath.Operator.greater: expr.Reset(new System.XPath.XPathGreaterExpr(expr.Release(), right)); break;
62 }
63 }
64 )*
65 )
66 {
67 return expr.Release();
68 }
69 ;
70
71 AdditiveExpr(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
72 ::=
73 ( MultiplicativeExpr:left{ expr.Reset(left); }
74 ( (PLUS{ op = System.XPath.Operator.plus; } | MINUS{ op = System.XPath.Operator.minus; })
75 MultiplicativeExpr:right!
76 {
77 switch (op)
78 {
79 case System.XPath.Operator.plus: expr.Reset(new System.XPath.XPathAddExpr(expr.Release(), right)); break;
80 case System.XPath.Operator.minus: expr.Reset(new System.XPath.XPathSubExpr(expr.Release(), right)); break;
81 }
82 }
83 )*
84 )
85 {
86 return expr.Release();
87 }
88 ;
89
90 MultiplicativeExpr(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
91 ::=
92 ( UnaryExpr:left{ expr.Reset(left); }
93 ( (STAR{ op = System.XPath.Operator.mul; }
94 | NAME
95 {
96 Token token = lexer.GetToken(pos);
97 switch (lexer.GetKeywordToken(token.match))
98 {
99 case DIV: op = System.XPath.Operator.div; break;
100 case MOD: op = System.XPath.Operator.mod; break;
101 default: pass = false; break;
102 }
103 }
104 )
105 UnaryExpr:right!
106 {
107 switch (op)
108 {
109 case System.XPath.Operator.mul: expr.Reset(new System.XPath.XPathMulExpr(expr.Release(), right)); break;
110 case System.XPath.Operator.div: expr.Reset(new System.XPath.XPathDivExpr(expr.Release(), right)); break;
111 case System.XPath.Operator.mod: expr.Reset(new System.XPath.XPathModExpr(expr.Release(), right)); break;
112 }
113 }
114 )*
115 )
116 {
117 return expr.Release();
118 }
119 ;
120
121 UnaryExpr : System.XPath.XPathExpr*
122 ::= MINUS UnaryExpr:subject{ return new System.XPath.XPathUnaryMinusExpr(subject); }
123 | UnionExpr:unionExpr{ return unionExpr; }
124 ;
125
126 UnionExpr(var UniquePtr<System.XPath.XPathExpr> expr) : System.XPath.XPathExpr*
127 ::= (PathExpr:left{ expr.Reset(left); } (UNION PathExpr:right{ expr.Reset(new System.XPath.XPathUnionExpr(expr.Release(), right)); })*)
128 {
129 return expr.Release();
130 }
131 ;
132
133 PathExpr(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
134 ::= (LocationPath:locationPath - FunctionCall:functionCall){ return locationPath; }
135 | (FilterExpr:filterExpr{ expr.Reset(filterExpr); } ((SLASHSLASH{ op = System.XPath.Operator.slashSlash; } | SLASH{ op = System.XPath.Operator.slash; }) RelativeLocationPath:right
136 {
137 switch (op)
138 {
139 case System.XPath.Operator.slashSlash:
140 {
141 return new System.XPath.XPathCombineStepExpr(expr.Release(),
142 new System.XPath.XPathCombineStepExpr(new System.XPath.XPathLocationStepExpr(System.Dom.Axis.descendantOrSelf, new System.XPath.XPathAnyNodeTest()), right));
143 }
144 case System.XPath.Operator.slash:
145 {
146 return new System.XPath.XPathCombineStepExpr(expr.Release(), right);
147 }
148 }
149 }
150 )?
151 )
152 {
153 return expr.Release();
154 }
155 ;
156
157 FilterExpr(var UniquePtr<System.XPath.XPathExpr> expr) : System.XPath.XPathExpr*
158 ::= (PrimaryExpr:primaryExpr{ expr.Reset(primaryExpr); } (Predicate:predicate{ expr.Reset(new System.XPath.XPathFilterExpr(expr.Release(), predicate)); })*)
159 {
160 return expr.Release();
161 }
162 ;
163
164 LocationPath : System.XPath.XPathExpr*
165 ::= AbsoluteLocationPath:absoluteLocationPath{ return absoluteLocationPath; }
166 | RelativeLocationPath:relativeLocationPath{ return relativeLocationPath; }
167 ;
168
169 AbsoluteLocationPath(var UniquePtr<System.XPath.XPathExpr> expr) : System.XPath.XPathExpr*
170 ::=
171 ( AbbreviatedAbsoluteLocationPath:abbreviatedAbsoluteLocationPath{ expr.Reset(abbreviatedAbsoluteLocationPath); }
172 | SLASH{ expr.Reset(new System.XPath.XPathRootNodeExpr()); } (RelativeLocationPath:right{ expr.Reset(new System.XPath.XPathCombineStepExpr(expr.Release(), right)); })?
173 )
174 {
175 return expr.Release();
176 }
177 ;
178
179 AbbreviatedAbsoluteLocationPath : System.XPath.XPathExpr*
180 ::= SLASHSLASH RelativeLocationPath:right
181 {
182 return new System.XPath.XPathCombineStepExpr(new System.XPath.XPathRootNodeExpr(), new System.XPath.XPathCombineStepExpr(
183 new System.XPath.XPathLocationStepExpr(System.Dom.Axis.descendantOrSelf, new System.XPath.XPathAnyNodeTest()), right));
184 }
185 ;
186
187 RelativeLocationPath(var UniquePtr<System.XPath.XPathExpr> expr, var System.XPath.Operator op) : System.XPath.XPathExpr*
188 ::=
189 (
190 Step:left{ expr.Reset(left); } ((SLASHSLASH{ op = System.XPath.Operator.slashSlash; } | SLASH{ op = System.XPath.Operator.slash; }) Step:right
191 {
192 switch (op)
193 {
194 case System.XPath.Operator.slashSlash:
195 {
196 expr.Reset(new System.XPath.XPathCombineStepExpr(expr.Release(), new System.XPath.XPathCombineStepExpr(
197 new System.XPath.XPathLocationStepExpr(System.Dom.Axis.descendantOrSelf, new System.XPath.XPathAnyNodeTest()), right)));
198 break;
199 }
200 case System.XPath.Operator.slash:
201 {
202 expr.Reset(new System.XPath.XPathCombineStepExpr(expr.Release(), right));
203 break;
204 }
205 }
206 }
207 )*
208 )
209 {
210 return expr.Release();
211 }
212 ;
213
214 Step(var UniquePtr<System.XPath.XPathLocationStepExpr> expr) : System.XPath.XPathLocationStepExpr*
215 ::=
216 ( AxisSpecifier:axis NodeTest:nodeTest{ expr.Reset(new System.XPath.XPathLocationStepExpr(axis, nodeTest)); } (Predicate:predicate{ expr->AddPredicate(predicate); })*
217 | AbbreviatedStep:abbreviatedStep{ expr.Reset(abbreviatedStep); }
218 )
219 {
220 return expr.Release();
221 }
222 ;
223
224 AxisSpecifier : System.Dom.Axis
225 ::= AxisName:axis COLONCOLON{ return axis;}
226 | AbbreviatedAxisSpecifier:abbreviatedAxisSpecifier{ return abbreviatedAxisSpecifier; }
227 ;
228
229 AxisName : System.Dom.Axis
230 ::= NAME
231 {
232 Token token = lexer.GetToken(pos);
233 switch (lexer.GetKeywordToken(token.match))
234 {
235 case ANCESTOR:
236 {
237 return System.Dom.Axis.ancestor;
238 }
239 case ANCESTOR_OR_SELF:
240 {
241 return System.Dom.Axis.ancestorOrSelf;
242 }
243 case ATTRIBUTE:
244 {
245 return System.Dom.Axis.attribute;
246 }
247 case CHILD :
248 {
249 return System.Dom.Axis.child;
250 }
251 case DESCENDANT:
252 {
253 return System.Dom.Axis.descendant;
254 }
255 case DESCENDANT_OR_SELF:
256 {
257 return System.Dom.Axis.descendantOrSelf;
258 }
259 case FOLLOWING:
260 {
261 return System.Dom.Axis.following;
262 }
263 case FOLLOWING_SIBLING:
264 {
265 return System.Dom.Axis.followingSibling;
266 }
267 case NAMESPACE:
268 {
269 return System.Dom.Axis.ns;
270 }
271 case PARENT:
272 {
273 return System.Dom.Axis.parent;
274 }
275 case PRECEDING:
276 {
277 return System.Dom.Axis.preceding;
278 }
279 case PRECEDING_SIBLING:
280 {
281 return System.Dom.Axis.precedingSibling;
282 }
283 case SELF:
284 {
285 return System.Dom.Axis.self;
286 }
287 default:
288 {
289 pass = false;
290 break;
291 }
292 }
293 }
294 ;
295
296 AbbreviatedAxisSpecifier : System.Dom.Axis
297 ::= AT{ return System.Dom.Axis.attribute; }
298 | empty{ return System.Dom.Axis.child; }
299 ;
300
301 NodeTest : System.XPath.XPathNodeTestExpr*
302 ::= NAME{ Token token = lexer.GetToken(pos); pass = lexer.GetKeywordToken(token.match) == PROCESSING_INSTRUCTION; } LPAREN Literal:pi RPAREN{ return new System.XPath.XPathPILiteralTest(pi); }
303 | NodeType:nodeType LPAREN RPAREN{ return nodeType; }
304 | NameTest:nameTest{ return nameTest; }
305 ;
306
307 NodeType : System.XPath.XPathNodeTestExpr*
308 ::= NAME
309 {
310 Token token = lexer.GetToken(pos);
311 switch (lexer.GetKeywordToken(token.match))
312 {
313 case COMMENT: return new System.XPath.XPathCommentNodeTest();
314 case TEXT: return new System.XPath.XPathTextNodeTest();
315 case PROCESSING_INSTRUCTION: return new System.XPath.XPathPINodeTest();
316 case NODE: return new System.XPath.XPathAnyNodeTest();
317 default:
318 {
319 pass = false;
320 break;
321 }
322 }
323 }
324 ;
325
326 NameTest : System.XPath.XPathNodeTestExpr*
327 ::= STAR{ return new System.XPath.XPathPrincipalNodeTest(); }
328 | NCName:ncname COLON STAR{ return new System.XPath.XPathPrefixTest(ncname); }
329 | QName:qname{ return new System.XPath.XPathNameTest(qname); }
330 ;
331
332 AbbreviatedStep : System.XPath.XPathLocationStepExpr*
333 ::= DOTDOT{ return new System.XPath.XPathLocationStepExpr(System.Dom.Axis.parent, new System.XPath.XPathAnyNodeTest()); }
334 | DOT{ return new System.XPath.XPathLocationStepExpr(System.Dom.Axis.self, new System.XPath.XPathAnyNodeTest()); }
335 ;
336
337 Literal : System.XPath.XPathExpr*
338 ::= DQSTRING
339 {
340 Token token = lexer.GetToken(pos);
341 ustring str = System.XPath.ParseDQString(lexer.FileName(), token);
342 return new System.XPath.XPathLiteral(str);
343 }
344 | SQSTRING
345 {
346 Token token = lexer.GetToken(pos);
347 ustring str = System.XPath.ParseSQString(lexer.FileName(), token);
348 return new System.XPath.XPathLiteral(str);
349 }
350 ;
351
352 Number : System.XPath.XPathExpr*
353 ::= NUMBER
354 {
355 Token token = lexer.GetToken(pos);
356 ustring str = token.match.ToString();
357 return new System.XPath.XPathNumberExpr(str);
358 }
359 ;
360
361 Predicate : System.XPath.XPathExpr*
362 ::= (LBRACKET PredicateExpr:expr RBRACKET){ return expr; }
363 ;
364
365 PredicateExpr : System.XPath.XPathExpr*
366 ::= Expr:expr{ return expr; }
367 ;
368
369 PrimaryExpr : System.XPath.XPathExpr*
370 ::= FunctionCall:functionCall{ return functionCall; }
371 | VariableReference:variableReference{ return variableReference; }
372 | (LPAREN Expr:expr RPAREN){ return expr; }
373 | Literal:literal{ return literal; }
374 | Number:number{ return number; }
375 ;
376
377 VariableReference : System.XPath.XPathExpr*
378 ::= (DOLLAR QName:qname){ return new System.XPath.XPathVariableReference(qname); }
379 ;
380
381 FunctionCall(var UniquePtr<System.XPath.XPathFunctionCall> functionCall) : System.XPath.XPathExpr*
382 ::= (FunctionName:functionName LPAREN{ functionCall.Reset(new System.XPath.XPathFunctionCall(functionName)); } (Argument:arg{ functionCall->AddArgument(arg); } % COMMA)? RPAREN)
383 {
384 return functionCall.Release();
385 }
386 ;
387
388 FunctionName : ustring
389 ::= (QName:qname - NodeType:nodeType){ return qname; }
390 ;
391
392 Argument : System.XPath.XPathExpr*
393 ::= Expr:expr{ return expr; }
394 ;
395
396 QName : ustring
397 ::= PrefixedName:prefixedName{ return prefixedName; }
398 | UnprefixedName:unprefixedName{ return unprefixedName; }
399 ;
400
401 PrefixedName : ustring
402 ::= (Prefix:prefix COLON LocalPart:localPart){ return prefix + u":" + localPart; }
403 ;
404
405 Prefix : ustring
406 ::= NCName:ncname{ return ncname; }
407 ;
408
409 UnprefixedName : ustring
410 ::= LocalPart:localPart{ return localPart; }
411 ;
412
413 LocalPart : ustring
414 ::= NCName:ncname{ return ncname; }
415 ;
416
417 NCName : ustring
418 ::= NAME{ Token token = lexer.GetToken(pos); return token.match.ToString(); }
419 ;
420
421 }