XPathGrammar.y revision cad810f21b803229eb11403f9209855525a25d57
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
52using namespace WebCore;
53using 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
75static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); }
76static 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
120Expr:
121    OrExpr
122    {
123        PARSER->m_topExpr = $1;
124    }
125    ;
126
127LocationPath:
128    RelativeLocationPath
129    {
130        $$->setAbsolute(false);
131    }
132    |
133    AbsoluteLocationPath
134    {
135        $$->setAbsolute(true);
136    }
137    ;
138
139AbsoluteLocationPath:
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
159RelativeLocationPath:
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
183Step:
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
245AxisSpecifier:
246    AXISNAME
247    |
248    '@'
249    {
250        $$ = Step::AttributeAxis;
251    }
252    ;
253
254NodeTest:
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
284OptionalPredicateList:
285    /* empty */
286    {
287        $$ = 0;
288    }
289    |
290    PredicateList
291    ;
292
293PredicateList:
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
309Predicate:
310    '[' Expr ']'
311    {
312        $$ = $2;
313    }
314    ;
315
316DescendantOrSelf:
317    SLASHSLASH
318    {
319        $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
320        PARSER->registerParseNode($$);
321    }
322    ;
323
324AbbreviatedStep:
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
338PrimaryExpr:
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
368FunctionCall:
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
389ArgumentList:
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
405Argument:
406    Expr
407    ;
408
409UnionExpr:
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
423PathExpr:
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
452FilterExpr:
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
464OrExpr:
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
476AndExpr:
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
488EqualityExpr:
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
500RelationalExpr:
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
512AdditiveExpr:
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
532MultiplicativeExpr:
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
544UnaryExpr:
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