• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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