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#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 "XPathStep.h" 40#include "XPathVariableReference.h" 41#include <wtf/FastMalloc.h> 42 43#define YYMALLOC fastMalloc 44#define YYFREE fastFree 45 46#define YYENABLE_NLS 0 47#define YYLTYPE_IS_TRIVIAL 1 48#define YYDEBUG 0 49#define YYMAXDEPTH 10000 50 51using namespace WebCore; 52using namespace XPath; 53 54%} 55 56%pure_parser 57%parse-param { WebCore::XPath::Parser* 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 75static int xpathyylex(YYSTYPE* yylval) { return Parser::current()->lex(yylval); } 76static void xpathyyerror(void*, 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 120Expr: 121 OrExpr 122 { 123 parser->m_topExpr = $1; 124 } 125 ; 126 127LocationPath: 128 RelativeLocationPath 129 { 130 $$->setAbsolute(false); 131 } 132 | 133 AbsoluteLocationPath 134 { 135 $$->setAbsolute(true); 136 } 137 ; 138 139AbsoluteLocationPath: 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 159RelativeLocationPath: 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 183Step: 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 245AxisSpecifier: 246 AXISNAME 247 | 248 '@' 249 { 250 $$ = Step::AttributeAxis; 251 } 252 ; 253 254NodeTest: 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 284OptionalPredicateList: 285 /* empty */ 286 { 287 $$ = 0; 288 } 289 | 290 PredicateList 291 ; 292 293PredicateList: 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 309Predicate: 310 '[' Expr ']' 311 { 312 $$ = $2; 313 } 314 ; 315 316DescendantOrSelf: 317 SLASHSLASH 318 { 319 $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest)); 320 parser->registerParseNode($$); 321 } 322 ; 323 324AbbreviatedStep: 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 338PrimaryExpr: 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 368FunctionCall: 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 389ArgumentList: 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 405Argument: 406 Expr 407 ; 408 409UnionExpr: 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 423PathExpr: 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 452FilterExpr: 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 464OrExpr: 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 476AndExpr: 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 488EqualityExpr: 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 500RelationalExpr: 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 512AdditiveExpr: 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 532MultiplicativeExpr: 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 544UnaryExpr: 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