1 /*
2 * Copyright 2005 Frerich Raabe <raabe@kde.org>
3 * Copyright (C) 2006 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 %{
29
30 #include "config.h"
31
32 #if ENABLE(XPATH)
33
34 #include "XPathFunctions.h"
35 #include "XPathNSResolver.h"
36 #include "XPathParser.h"
37 #include "XPathPath.h"
38 #include "XPathPredicate.h"
39 #include "XPathVariableReference.h"
40 #include <wtf/FastMalloc.h>
41
42 #define YYMALLOC fastMalloc
43 #define YYFREE fastFree
44
45 #define YYENABLE_NLS 0
46 #define YYLTYPE_IS_TRIVIAL 1
47 #define YYDEBUG 0
48 #define YYMAXDEPTH 10000
49 #define YYPARSE_PARAM parserParameter
50 #define PARSER static_cast<Parser*>(parserParameter)
51
52 using namespace WebCore;
53 using namespace XPath;
54
55 %}
56
57 %pure_parser
58
59 %union
60 {
61 Step::Axis axis;
62 Step::NodeTest* nodeTest;
63 NumericOp::Opcode numop;
64 EqTestOp::Opcode eqop;
65 String* str;
66 Expression* expr;
67 Vector<Predicate*>* predList;
68 Vector<Expression*>* argList;
69 Step* step;
70 LocationPath* locationPath;
71 }
72
73 %{
74
xpathyylex(YYSTYPE * yylval)75 static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); }
xpathyyerror(const char *)76 static void xpathyyerror(const char*) { }
77
78 %}
79
80 %left <numop> MULOP
81 %left <eqop> EQOP RELOP
82 %left PLUS MINUS
83 %left OR AND
84 %token <axis> AXISNAME
85 %token <str> NODETYPE PI FUNCTIONNAME LITERAL
86 %token <str> VARIABLEREFERENCE NUMBER
87 %token DOTDOT SLASHSLASH
88 %token <str> NAMETEST
89 %token XPATH_ERROR
90
91 %type <locationPath> LocationPath
92 %type <locationPath> AbsoluteLocationPath
93 %type <locationPath> RelativeLocationPath
94 %type <step> Step
95 %type <axis> AxisSpecifier
96 %type <step> DescendantOrSelf
97 %type <nodeTest> NodeTest
98 %type <expr> Predicate
99 %type <predList> OptionalPredicateList
100 %type <predList> PredicateList
101 %type <step> AbbreviatedStep
102 %type <expr> Expr
103 %type <expr> PrimaryExpr
104 %type <expr> FunctionCall
105 %type <argList> ArgumentList
106 %type <expr> Argument
107 %type <expr> UnionExpr
108 %type <expr> PathExpr
109 %type <expr> FilterExpr
110 %type <expr> OrExpr
111 %type <expr> AndExpr
112 %type <expr> EqualityExpr
113 %type <expr> RelationalExpr
114 %type <expr> AdditiveExpr
115 %type <expr> MultiplicativeExpr
116 %type <expr> UnaryExpr
117
118 %%
119
120 Expr:
121 OrExpr
122 {
123 PARSER->m_topExpr = $1;
124 }
125 ;
126
127 LocationPath:
128 RelativeLocationPath
129 {
130 $$->setAbsolute(false);
131 }
132 |
133 AbsoluteLocationPath
134 {
135 $$->setAbsolute(true);
136 }
137 ;
138
139 AbsoluteLocationPath:
140 '/'
141 {
142 $$ = new LocationPath;
143 PARSER->registerParseNode($$);
144 }
145 |
146 '/' RelativeLocationPath
147 {
148 $$ = $2;
149 }
150 |
151 DescendantOrSelf RelativeLocationPath
152 {
153 $$ = $2;
154 $$->insertFirstStep($1);
155 PARSER->unregisterParseNode($1);
156 }
157 ;
158
159 RelativeLocationPath:
160 Step
161 {
162 $$ = new LocationPath;
163 $$->appendStep($1);
164 PARSER->unregisterParseNode($1);
165 PARSER->registerParseNode($$);
166 }
167 |
168 RelativeLocationPath '/' Step
169 {
170 $$->appendStep($3);
171 PARSER->unregisterParseNode($3);
172 }
173 |
174 RelativeLocationPath DescendantOrSelf Step
175 {
176 $$->appendStep($2);
177 $$->appendStep($3);
178 PARSER->unregisterParseNode($2);
179 PARSER->unregisterParseNode($3);
180 }
181 ;
182
183 Step:
184 NodeTest OptionalPredicateList
185 {
186 if ($2) {
187 $$ = new Step(Step::ChildAxis, *$1, *$2);
188 PARSER->deletePredicateVector($2);
189 } else
190 $$ = new Step(Step::ChildAxis, *$1);
191 PARSER->deleteNodeTest($1);
192 PARSER->registerParseNode($$);
193 }
194 |
195 NAMETEST OptionalPredicateList
196 {
197 String localName;
198 String namespaceURI;
199 if (!PARSER->expandQName(*$1, localName, namespaceURI)) {
200 PARSER->m_gotNamespaceError = true;
201 YYABORT;
202 }
203
204 if ($2) {
205 $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$2);
206 PARSER->deletePredicateVector($2);
207 } else
208 $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
209 PARSER->deleteString($1);
210 PARSER->registerParseNode($$);
211 }
212 |
213 AxisSpecifier NodeTest OptionalPredicateList
214 {
215 if ($3) {
216 $$ = new Step($1, *$2, *$3);
217 PARSER->deletePredicateVector($3);
218 } else
219 $$ = new Step($1, *$2);
220 PARSER->deleteNodeTest($2);
221 PARSER->registerParseNode($$);
222 }
223 |
224 AxisSpecifier NAMETEST OptionalPredicateList
225 {
226 String localName;
227 String namespaceURI;
228 if (!PARSER->expandQName(*$2, localName, namespaceURI)) {
229 PARSER->m_gotNamespaceError = true;
230 YYABORT;
231 }
232
233 if ($3) {
234 $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$3);
235 PARSER->deletePredicateVector($3);
236 } else
237 $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
238 PARSER->deleteString($2);
239 PARSER->registerParseNode($$);
240 }
241 |
242 AbbreviatedStep
243 ;
244
245 AxisSpecifier:
246 AXISNAME
247 |
248 '@'
249 {
250 $$ = Step::AttributeAxis;
251 }
252 ;
253
254 NodeTest:
255 NODETYPE '(' ')'
256 {
257 if (*$1 == "node")
258 $$ = new Step::NodeTest(Step::NodeTest::AnyNodeTest);
259 else if (*$1 == "text")
260 $$ = new Step::NodeTest(Step::NodeTest::TextNodeTest);
261 else if (*$1 == "comment")
262 $$ = new Step::NodeTest(Step::NodeTest::CommentNodeTest);
263
264 PARSER->deleteString($1);
265 PARSER->registerNodeTest($$);
266 }
267 |
268 PI '(' ')'
269 {
270 $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest);
271 PARSER->deleteString($1);
272 PARSER->registerNodeTest($$);
273 }
274 |
275 PI '(' LITERAL ')'
276 {
277 $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest, $3->stripWhiteSpace());
278 PARSER->deleteString($1);
279 PARSER->deleteString($3);
280 PARSER->registerNodeTest($$);
281 }
282 ;
283
284 OptionalPredicateList:
285 /* empty */
286 {
287 $$ = 0;
288 }
289 |
290 PredicateList
291 ;
292
293 PredicateList:
294 Predicate
295 {
296 $$ = new Vector<Predicate*>;
297 $$->append(new Predicate($1));
298 PARSER->unregisterParseNode($1);
299 PARSER->registerPredicateVector($$);
300 }
301 |
302 PredicateList Predicate
303 {
304 $$->append(new Predicate($2));
305 PARSER->unregisterParseNode($2);
306 }
307 ;
308
309 Predicate:
310 '[' Expr ']'
311 {
312 $$ = $2;
313 }
314 ;
315
316 DescendantOrSelf:
317 SLASHSLASH
318 {
319 $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
320 PARSER->registerParseNode($$);
321 }
322 ;
323
324 AbbreviatedStep:
325 '.'
326 {
327 $$ = new Step(Step::SelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
328 PARSER->registerParseNode($$);
329 }
330 |
331 DOTDOT
332 {
333 $$ = new Step(Step::ParentAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
334 PARSER->registerParseNode($$);
335 }
336 ;
337
338 PrimaryExpr:
339 VARIABLEREFERENCE
340 {
341 $$ = new VariableReference(*$1);
342 PARSER->deleteString($1);
343 PARSER->registerParseNode($$);
344 }
345 |
346 '(' Expr ')'
347 {
348 $$ = $2;
349 }
350 |
351 LITERAL
352 {
353 $$ = new StringExpression(*$1);
354 PARSER->deleteString($1);
355 PARSER->registerParseNode($$);
356 }
357 |
358 NUMBER
359 {
360 $$ = new Number($1->toDouble());
361 PARSER->deleteString($1);
362 PARSER->registerParseNode($$);
363 }
364 |
365 FunctionCall
366 ;
367
368 FunctionCall:
369 FUNCTIONNAME '(' ')'
370 {
371 $$ = createFunction(*$1);
372 if (!$$)
373 YYABORT;
374 PARSER->deleteString($1);
375 PARSER->registerParseNode($$);
376 }
377 |
378 FUNCTIONNAME '(' ArgumentList ')'
379 {
380 $$ = createFunction(*$1, *$3);
381 if (!$$)
382 YYABORT;
383 PARSER->deleteString($1);
384 PARSER->deleteExpressionVector($3);
385 PARSER->registerParseNode($$);
386 }
387 ;
388
389 ArgumentList:
390 Argument
391 {
392 $$ = new Vector<Expression*>;
393 $$->append($1);
394 PARSER->unregisterParseNode($1);
395 PARSER->registerExpressionVector($$);
396 }
397 |
398 ArgumentList ',' Argument
399 {
400 $$->append($3);
401 PARSER->unregisterParseNode($3);
402 }
403 ;
404
405 Argument:
406 Expr
407 ;
408
409 UnionExpr:
410 PathExpr
411 |
412 UnionExpr '|' PathExpr
413 {
414 $$ = new Union;
415 $$->addSubExpression($1);
416 $$->addSubExpression($3);
417 PARSER->unregisterParseNode($1);
418 PARSER->unregisterParseNode($3);
419 PARSER->registerParseNode($$);
420 }
421 ;
422
423 PathExpr:
424 LocationPath
425 {
426 $$ = $1;
427 }
428 |
429 FilterExpr
430 |
431 FilterExpr '/' RelativeLocationPath
432 {
433 $3->setAbsolute(true);
434 $$ = new Path(static_cast<Filter*>($1), $3);
435 PARSER->unregisterParseNode($1);
436 PARSER->unregisterParseNode($3);
437 PARSER->registerParseNode($$);
438 }
439 |
440 FilterExpr DescendantOrSelf RelativeLocationPath
441 {
442 $3->insertFirstStep($2);
443 $3->setAbsolute(true);
444 $$ = new Path(static_cast<Filter*>($1), $3);
445 PARSER->unregisterParseNode($1);
446 PARSER->unregisterParseNode($2);
447 PARSER->unregisterParseNode($3);
448 PARSER->registerParseNode($$);
449 }
450 ;
451
452 FilterExpr:
453 PrimaryExpr
454 |
455 PrimaryExpr PredicateList
456 {
457 $$ = new Filter($1, *$2);
458 PARSER->unregisterParseNode($1);
459 PARSER->deletePredicateVector($2);
460 PARSER->registerParseNode($$);
461 }
462 ;
463
464 OrExpr:
465 AndExpr
466 |
467 OrExpr OR AndExpr
468 {
469 $$ = new LogicalOp(LogicalOp::OP_Or, $1, $3);
470 PARSER->unregisterParseNode($1);
471 PARSER->unregisterParseNode($3);
472 PARSER->registerParseNode($$);
473 }
474 ;
475
476 AndExpr:
477 EqualityExpr
478 |
479 AndExpr AND EqualityExpr
480 {
481 $$ = new LogicalOp(LogicalOp::OP_And, $1, $3);
482 PARSER->unregisterParseNode($1);
483 PARSER->unregisterParseNode($3);
484 PARSER->registerParseNode($$);
485 }
486 ;
487
488 EqualityExpr:
489 RelationalExpr
490 |
491 EqualityExpr EQOP RelationalExpr
492 {
493 $$ = new EqTestOp($2, $1, $3);
494 PARSER->unregisterParseNode($1);
495 PARSER->unregisterParseNode($3);
496 PARSER->registerParseNode($$);
497 }
498 ;
499
500 RelationalExpr:
501 AdditiveExpr
502 |
503 RelationalExpr RELOP AdditiveExpr
504 {
505 $$ = new EqTestOp($2, $1, $3);
506 PARSER->unregisterParseNode($1);
507 PARSER->unregisterParseNode($3);
508 PARSER->registerParseNode($$);
509 }
510 ;
511
512 AdditiveExpr:
513 MultiplicativeExpr
514 |
515 AdditiveExpr PLUS MultiplicativeExpr
516 {
517 $$ = new NumericOp(NumericOp::OP_Add, $1, $3);
518 PARSER->unregisterParseNode($1);
519 PARSER->unregisterParseNode($3);
520 PARSER->registerParseNode($$);
521 }
522 |
523 AdditiveExpr MINUS MultiplicativeExpr
524 {
525 $$ = new NumericOp(NumericOp::OP_Sub, $1, $3);
526 PARSER->unregisterParseNode($1);
527 PARSER->unregisterParseNode($3);
528 PARSER->registerParseNode($$);
529 }
530 ;
531
532 MultiplicativeExpr:
533 UnaryExpr
534 |
535 MultiplicativeExpr MULOP UnaryExpr
536 {
537 $$ = new NumericOp($2, $1, $3);
538 PARSER->unregisterParseNode($1);
539 PARSER->unregisterParseNode($3);
540 PARSER->registerParseNode($$);
541 }
542 ;
543
544 UnaryExpr:
545 UnionExpr
546 |
547 MINUS UnaryExpr
548 {
549 $$ = new Negative;
550 $$->addSubExpression($2);
551 PARSER->unregisterParseNode($2);
552 PARSER->registerParseNode($$);
553 }
554 ;
555
556 %%
557
558 #endif
559