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