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