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 #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 75 static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); } 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