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