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#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 49using namespace blink; 50using 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 73static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); } 74static 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 118Expr: 119 OrExpr 120 { 121 parser->m_topExpr = $1; 122 } 123 ; 124 125LocationPath: 126 RelativeLocationPath 127 { 128 $$->setAbsolute(false); 129 } 130 | 131 AbsoluteLocationPath 132 { 133 $$->setAbsolute(true); 134 } 135 ; 136 137AbsoluteLocationPath: 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 157RelativeLocationPath: 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 181Step: 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 243AxisSpecifier: 244 AXISNAME 245 | 246 '@' 247 { 248 $$ = Step::AttributeAxis; 249 } 250 ; 251 252NodeTest: 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 282OptionalPredicateList: 283 /* empty */ 284 { 285 $$ = 0; 286 } 287 | 288 PredicateList 289 ; 290 291PredicateList: 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 307Predicate: 308 '[' Expr ']' 309 { 310 $$ = $2; 311 } 312 ; 313 314DescendantOrSelf: 315 SLASHSLASH 316 { 317 $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); 318 parser->registerParseNode($$); 319 } 320 ; 321 322AbbreviatedStep: 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 336PrimaryExpr: 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 366FunctionCall: 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 387ArgumentList: 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 403Argument: 404 Expr 405 ; 406 407UnionExpr: 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 421PathExpr: 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 450FilterExpr: 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 462OrExpr: 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 474AndExpr: 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 486EqualityExpr: 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 498RelationalExpr: 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 510AdditiveExpr: 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 530MultiplicativeExpr: 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 542UnaryExpr: 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