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>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
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"
41 #define YYMALLOC fastMalloc
42 #define YYFREE fastFree
44 #define YYENABLE_NLS 0
45 #define YYLTYPE_IS_TRIVIAL 1
47 #define YYMAXDEPTH 10000
49 using namespace blink;
50 using namespace XPath;
55 %parse-param { blink::XPath::Parser* parser }
59 blink::XPath::Step::Axis axis;
60 blink::XPath::Step::NodeTest* nodeTest;
61 blink::XPath::NumericOp::Opcode numop;
62 blink::XPath::EqTestOp::Opcode eqop;
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;
73 static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); }
74 static void xpathyyerror(void*, const char*) { }
79 %left <eqop> EQOP RELOP
82 %token <axis> AXISNAME
83 %token <str> NODETYPE PI FUNCTIONNAME LITERAL
84 %token <str> VARIABLEREFERENCE NUMBER
85 %token DOTDOT SLASHSLASH
89 %type <locationPath> LocationPath
90 %type <locationPath> AbsoluteLocationPath
91 %type <locationPath> RelativeLocationPath
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
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
110 %type <expr> EqualityExpr
111 %type <expr> RelationalExpr
112 %type <expr> AdditiveExpr
113 %type <expr> MultiplicativeExpr
114 %type <expr> UnaryExpr
121 parser->m_topExpr = $1;
128 $$->setAbsolute(false);
133 $$->setAbsolute(true);
137 AbsoluteLocationPath:
140 $$ = new LocationPath;
141 parser->registerParseNode($$);
144 '/' RelativeLocationPath
149 DescendantOrSelf RelativeLocationPath
152 $$->insertFirstStep($1);
153 parser->unregisterParseNode($1);
157 RelativeLocationPath:
160 $$ = new LocationPath;
162 parser->unregisterParseNode($1);
163 parser->registerParseNode($$);
166 RelativeLocationPath '/' Step
169 parser->unregisterParseNode($3);
172 RelativeLocationPath DescendantOrSelf Step
176 parser->unregisterParseNode($2);
177 parser->unregisterParseNode($3);
182 NodeTest OptionalPredicateList
185 $$ = new Step(Step::ChildAxis, *$1, *$2);
186 parser->deletePredicateVector($2);
188 $$ = new Step(Step::ChildAxis, *$1);
189 parser->deleteNodeTest($1);
190 parser->registerParseNode($$);
193 NAMETEST OptionalPredicateList
195 AtomicString localName;
196 AtomicString namespaceURI;
197 if (!parser->expandQName(*$1, localName, namespaceURI)) {
198 parser->m_gotNamespaceError = true;
203 $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$2);
204 parser->deletePredicateVector($2);
206 $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
207 parser->deleteString($1);
208 parser->registerParseNode($$);
211 AxisSpecifier NodeTest OptionalPredicateList
214 $$ = new Step($1, *$2, *$3);
215 parser->deletePredicateVector($3);
217 $$ = new Step($1, *$2);
218 parser->deleteNodeTest($2);
219 parser->registerParseNode($$);
222 AxisSpecifier NAMETEST OptionalPredicateList
224 AtomicString localName;
225 AtomicString namespaceURI;
226 if (!parser->expandQName(*$2, localName, namespaceURI)) {
227 parser->m_gotNamespaceError = true;
232 $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), *$3);
233 parser->deletePredicateVector($3);
235 $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
236 parser->deleteString($2);
237 parser->registerParseNode($$);
248 $$ = Step::AttributeAxis;
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);
262 parser->deleteString($1);
263 parser->registerNodeTest($$);
268 $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest);
269 parser->deleteString($1);
270 parser->registerNodeTest($$);
275 $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest, $3->stripWhiteSpace());
276 parser->deleteString($1);
277 parser->deleteString($3);
278 parser->registerNodeTest($$);
282 OptionalPredicateList:
294 $$ = new WillBeHeapVector<OwnPtrWillBeMember<Predicate> >;
295 $$->append(adoptPtrWillBeNoop(new Predicate(adoptPtrWillBeNoop($1))));
296 parser->unregisterParseNode($1);
297 parser->registerPredicateVector($$);
300 PredicateList Predicate
302 $$->append(adoptPtrWillBeNoop(new Predicate(adoptPtrWillBeNoop($2))));
303 parser->unregisterParseNode($2);
317 $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
318 parser->registerParseNode($$);
325 $$ = new Step(Step::SelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
326 parser->registerParseNode($$);
331 $$ = new Step(Step::ParentAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
332 parser->registerParseNode($$);
339 $$ = new VariableReference(*$1);
340 parser->deleteString($1);
341 parser->registerParseNode($$);
351 $$ = new StringExpression(*$1);
352 parser->deleteString($1);
353 parser->registerParseNode($$);
358 $$ = new Number($1->toDouble());
359 parser->deleteString($1);
360 parser->registerParseNode($$);
369 $$ = createFunction(*$1);
372 parser->deleteString($1);
373 parser->registerParseNode($$);
376 FUNCTIONNAME '(' ArgumentList ')'
378 $$ = createFunction(*$1, *$3);
381 parser->deleteString($1);
382 parser->deleteExpressionVector($3);
383 parser->registerParseNode($$);
390 $$ = new WillBeHeapVector<OwnPtrWillBeMember<Expression> >;
391 $$->append(adoptPtrWillBeNoop($1));
392 parser->unregisterParseNode($1);
393 parser->registerExpressionVector($$);
396 ArgumentList ',' Argument
398 $$->append(adoptPtrWillBeNoop($3));
399 parser->unregisterParseNode($3);
410 UnionExpr '|' PathExpr
413 $$->addSubExpression(adoptPtrWillBeNoop($1));
414 $$->addSubExpression(adoptPtrWillBeNoop($3));
415 parser->unregisterParseNode($1);
416 parser->unregisterParseNode($3);
417 parser->registerParseNode($$);
429 FilterExpr '/' RelativeLocationPath
431 $3->setAbsolute(true);
432 $$ = new Path($1, $3);
433 parser->unregisterParseNode($1);
434 parser->unregisterParseNode($3);
435 parser->registerParseNode($$);
438 FilterExpr DescendantOrSelf RelativeLocationPath
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($$);
453 PrimaryExpr PredicateList
455 $$ = new Filter(adoptPtrWillBeNoop($1), *$2);
456 parser->unregisterParseNode($1);
457 parser->deletePredicateVector($2);
458 parser->registerParseNode($$);
467 $$ = new LogicalOp(LogicalOp::OP_Or, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
468 parser->unregisterParseNode($1);
469 parser->unregisterParseNode($3);
470 parser->registerParseNode($$);
477 AndExpr AND EqualityExpr
479 $$ = new LogicalOp(LogicalOp::OP_And, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
480 parser->unregisterParseNode($1);
481 parser->unregisterParseNode($3);
482 parser->registerParseNode($$);
489 EqualityExpr EQOP RelationalExpr
491 $$ = new EqTestOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
492 parser->unregisterParseNode($1);
493 parser->unregisterParseNode($3);
494 parser->registerParseNode($$);
501 RelationalExpr RELOP AdditiveExpr
503 $$ = new EqTestOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
504 parser->unregisterParseNode($1);
505 parser->unregisterParseNode($3);
506 parser->registerParseNode($$);
513 AdditiveExpr PLUS MultiplicativeExpr
515 $$ = new NumericOp(NumericOp::OP_Add, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
516 parser->unregisterParseNode($1);
517 parser->unregisterParseNode($3);
518 parser->registerParseNode($$);
521 AdditiveExpr MINUS MultiplicativeExpr
523 $$ = new NumericOp(NumericOp::OP_Sub, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
524 parser->unregisterParseNode($1);
525 parser->unregisterParseNode($3);
526 parser->registerParseNode($$);
533 MultiplicativeExpr MULOP UnaryExpr
535 $$ = new NumericOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
536 parser->unregisterParseNode($1);
537 parser->unregisterParseNode($3);
538 parser->registerParseNode($$);
548 $$->addSubExpression(adoptPtrWillBeNoop($2));
549 parser->unregisterParseNode($2);
550 parser->registerParseNode($$);