Unreviewed, rolling out r161051.
[WebKit-https.git] / Source / WebCore / xml / XPathGrammar.y
1 /*
2  * Copyright 2005 Frerich Raabe <raabe@kde.org>
3  * Copyright (C) 2006, 2013 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 "XPathFunctions.h"
33 #include "XPathParser.h"
34 #include "XPathPath.h"
35 #include "XPathVariableReference.h"
36
37 #define YYMALLOC fastMalloc
38 #define YYFREE fastFree
39
40 #define YYENABLE_NLS 0
41 #define YYLTYPE_IS_TRIVIAL 1
42 #define YYDEBUG 0
43 #define YYMAXDEPTH 10000
44
45 using namespace WebCore;
46 using namespace XPath;
47
48 %}
49
50 %pure_parser
51 %lex-param { parser }
52 %parse-param { Parser& parser }
53
54 %union { NumericOp::Opcode numericOpcode; }
55 %left <numericOpcode> MULOP
56
57 %union { EqTestOp::Opcode equalityTestOpcode; }
58 %left <equalityTestOpcode> EQOP RELOP
59
60 %left PLUS MINUS
61
62 %left OR AND
63
64 %union { StringImpl* string; }
65 %token <string> FUNCTIONNAME LITERAL NAMETEST NUMBER NODETYPE VARIABLEREFERENCE
66 %destructor { if ($$) $$->deref(); } FUNCTIONNAME LITERAL NAMETEST NUMBER NODETYPE VARIABLEREFERENCE
67
68 %union { Step::Axis axis; }
69 %token <axis> AXISNAME
70 %type <axis> AxisSpecifier
71
72 %token COMMENT DOTDOT PI NODE SLASHSLASH TEXT XPATH_ERROR
73
74 %union { LocationPath* locationPath; }
75 %type <locationPath> LocationPath AbsoluteLocationPath RelativeLocationPath
76 %destructor { delete $$; } LocationPath AbsoluteLocationPath RelativeLocationPath
77
78 %union { Step::NodeTest* nodeTest; }
79 %type <nodeTest> NodeTest
80 %destructor { delete $$; } NodeTest
81
82 %union { Vector<std::unique_ptr<Expression>>* expressionVector; }
83 %type <expressionVector> ArgumentList PredicateList OptionalPredicateList
84 %destructor { delete $$; } ArgumentList PredicateList OptionalPredicateList
85
86 %union { Step* step; }
87 %type <step> Step AbbreviatedStep DescendantOrSelf
88 %destructor { delete $$; } Step AbbreviatedStep DescendantOrSelf
89
90 %union { Expression* expression; }
91 %type <expression> AdditiveExpr AndExpr Argument EqualityExpr Expr FilterExpr FunctionCall MultiplicativeExpr OrExpr PathExpr Predicate PrimaryExpr RelationalExpr UnaryExpr UnionExpr
92 %destructor { delete $$; } AdditiveExpr AndExpr Argument EqualityExpr Expr FilterExpr FunctionCall MultiplicativeExpr OrExpr PathExpr Predicate PrimaryExpr RelationalExpr UnaryExpr UnionExpr
93
94 %{
95
96 static int xpathyylex(YYSTYPE* yylval, Parser& parser) { return parser.lex(*yylval); }
97 static void xpathyyerror(Parser&, const char*) { }
98
99 %}
100
101 %%
102
103 Top:
104     Expr
105     {
106         parser.setParseResult(std::unique_ptr<Expression>($1));
107     }
108     ;
109
110 Expr:
111     OrExpr
112     ;
113
114 LocationPath:
115     AbsoluteLocationPath
116     {
117         $$ = $1;
118         $$->setAbsolute();
119     }
120     |
121     RelativeLocationPath
122     ;
123
124 AbsoluteLocationPath:
125     '/'
126     {
127         $$ = new LocationPath;
128     }
129     |
130     '/' RelativeLocationPath
131     {
132         $$ = $2;
133     }
134     |
135     DescendantOrSelf RelativeLocationPath
136     {
137         $$ = $2;
138         $$->prependStep(std::unique_ptr<Step>($1));
139     }
140     ;
141
142 RelativeLocationPath:
143     Step
144     {
145         $$ = new LocationPath;
146         $$->appendStep(std::unique_ptr<Step>($1));
147     }
148     |
149     RelativeLocationPath '/' Step
150     {
151         $$ = $1;
152         $$->appendStep(std::unique_ptr<Step>($3));
153     }
154     |
155     RelativeLocationPath DescendantOrSelf Step
156     {
157         $$ = $1;
158         $$->appendStep(std::unique_ptr<Step>($2));
159         $$->appendStep(std::unique_ptr<Step>($3));
160     }
161     ;
162
163 Step:
164     NodeTest OptionalPredicateList
165     {
166         std::unique_ptr<Step::NodeTest> nodeTest($1);
167         std::unique_ptr<Vector<std::unique_ptr<Expression>>> predicateList($2);
168         if (predicateList)
169             $$ = new Step(Step::ChildAxis, std::move(*nodeTest), std::move(*predicateList));
170         else
171             $$ = new Step(Step::ChildAxis, std::move(*nodeTest));
172     }
173     |
174     NAMETEST OptionalPredicateList
175     {
176         String nametest = adoptRef($1);
177         std::unique_ptr<Vector<std::unique_ptr<Expression>>> predicateList($2);
178
179         String localName;
180         String namespaceURI;
181         if (!parser.expandQualifiedName(nametest, localName, namespaceURI)) {
182             $$ = nullptr;
183             YYABORT;
184         }
185
186         if (predicateList)
187             $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), std::move(*predicateList));
188         else
189             $$ = new Step(Step::ChildAxis, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
190     }
191     |
192     AxisSpecifier NodeTest OptionalPredicateList
193     {
194         std::unique_ptr<Step::NodeTest> nodeTest($2);
195         std::unique_ptr<Vector<std::unique_ptr<Expression>>> predicateList($3);
196
197         if (predicateList)
198             $$ = new Step($1, std::move(*nodeTest), std::move(*predicateList));
199         else
200             $$ = new Step($1, std::move(*nodeTest));
201     }
202     |
203     AxisSpecifier NAMETEST OptionalPredicateList
204     {
205         String nametest = adoptRef($2);
206         std::unique_ptr<Vector<std::unique_ptr<Expression>>> predicateList($3);
207
208         String localName;
209         String namespaceURI;
210         if (!parser.expandQualifiedName(nametest, localName, namespaceURI)) {
211             $$ = nullptr;
212             YYABORT;
213         }
214
215         if (predicateList)
216             $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI), std::move(*predicateList));
217         else
218             $$ = new Step($1, Step::NodeTest(Step::NodeTest::NameTest, localName, namespaceURI));
219     }
220     |
221     AbbreviatedStep
222     ;
223
224 AxisSpecifier:
225     AXISNAME
226     |
227     '@'
228     {
229         $$ = Step::AttributeAxis;
230     }
231     ;
232
233 NodeTest:
234     NODE '(' ')'
235     {
236         $$ = new Step::NodeTest(Step::NodeTest::AnyNodeTest);
237     }
238     |
239     TEXT '(' ')'
240     {
241         $$ = new Step::NodeTest(Step::NodeTest::TextNodeTest);
242     }
243     |
244     COMMENT '(' ')'
245     {
246         $$ = new Step::NodeTest(Step::NodeTest::CommentNodeTest);
247     }
248     |
249     PI '(' ')'
250     {
251         $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest);
252     }
253     |
254     PI '(' LITERAL ')'
255     {
256         String literal = adoptRef($3);
257         $$ = new Step::NodeTest(Step::NodeTest::ProcessingInstructionNodeTest, literal.stripWhiteSpace());
258     }
259     ;
260
261 OptionalPredicateList:
262     /* empty */
263     {
264         $$ = nullptr;
265     }
266     |
267     PredicateList
268     ;
269
270 PredicateList:
271     Predicate
272     {
273         $$ = new Vector<std::unique_ptr<Expression>>;
274         $$->append(std::unique_ptr<Expression>($1));
275     }
276     |
277     PredicateList Predicate
278     {
279         $$ = $1;
280         $$->append(std::unique_ptr<Expression>($2));
281     }
282     ;
283
284 Predicate:
285     '[' Expr ']'
286     {
287         $$ = $2;
288     }
289     ;
290
291 DescendantOrSelf:
292     SLASHSLASH
293     {
294         $$ = new Step(Step::DescendantOrSelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
295     }
296     ;
297
298 AbbreviatedStep:
299     '.'
300     {
301         $$ = new Step(Step::SelfAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
302     }
303     |
304     DOTDOT
305     {
306         $$ = new Step(Step::ParentAxis, Step::NodeTest(Step::NodeTest::AnyNodeTest));
307     }
308     ;
309
310 PrimaryExpr:
311     VARIABLEREFERENCE
312     {
313         String name = adoptRef($1);
314         $$ = new VariableReference(name);
315     }
316     |
317     '(' Expr ')'
318     {
319         $$ = $2;
320     }
321     |
322     LITERAL
323     {
324         String literal = adoptRef($1);
325         $$ = new StringExpression(std::move(literal));
326     }
327     |
328     NUMBER
329     {
330         String numeral = adoptRef($1);
331         $$ = new Number(numeral.toDouble());
332     }
333     |
334     FunctionCall
335     ;
336
337 FunctionCall:
338     FUNCTIONNAME '(' ')'
339     {
340         String name = adoptRef($1);
341         $$ = XPath::Function::create(name).release();
342         if (!$$)
343             YYABORT;
344     }
345     |
346     FUNCTIONNAME '(' ArgumentList ')'
347     {
348         String name = adoptRef($1);
349         std::unique_ptr<Vector<std::unique_ptr<Expression>>> argumentList($3);
350         $$ = XPath::Function::create(name, std::move(*argumentList)).release();
351         if (!$$)
352             YYABORT;
353     }
354     ;
355
356 ArgumentList:
357     Argument
358     {
359         $$ = new Vector<std::unique_ptr<Expression>>;
360         $$->append(std::unique_ptr<Expression>($1));
361     }
362     |
363     ArgumentList ',' Argument
364     {
365         $$ = $1;
366         $$->append(std::unique_ptr<Expression>($3));
367     }
368     ;
369
370 Argument:
371     Expr
372     ;
373
374 UnionExpr:
375     PathExpr
376     |
377     UnionExpr '|' PathExpr
378     {
379         $$ = new Union(std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
380     }
381     ;
382
383 PathExpr:
384     LocationPath
385     {
386         $$ = $1;
387     }
388     |
389     FilterExpr
390     |
391     FilterExpr '/' RelativeLocationPath
392     {
393         $3->setAbsolute();
394         $$ = new Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3));
395     }
396     |
397     FilterExpr DescendantOrSelf RelativeLocationPath
398     {
399         $3->prependStep(std::unique_ptr<Step>($2));
400         $3->setAbsolute();
401         $$ = new Path(std::unique_ptr<Expression>($1), std::unique_ptr<LocationPath>($3));
402     }
403     ;
404
405 FilterExpr:
406     PrimaryExpr
407     |
408     PrimaryExpr PredicateList
409     {
410         std::unique_ptr<Vector<std::unique_ptr<Expression>>> predicateList($2);
411         $$ = new Filter(std::unique_ptr<Expression>($1), std::move(*predicateList));
412     }
413     ;
414
415 OrExpr:
416     AndExpr
417     |
418     OrExpr OR AndExpr
419     {
420         $$ = new LogicalOp(LogicalOp::OP_Or, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
421     }
422     ;
423
424 AndExpr:
425     EqualityExpr
426     |
427     AndExpr AND EqualityExpr
428     {
429         $$ = new LogicalOp(LogicalOp::OP_And, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
430     }
431     ;
432
433 EqualityExpr:
434     RelationalExpr
435     |
436     EqualityExpr EQOP RelationalExpr
437     {
438         $$ = new EqTestOp($2, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
439     }
440     ;
441
442 RelationalExpr:
443     AdditiveExpr
444     |
445     RelationalExpr RELOP AdditiveExpr
446     {
447         $$ = new EqTestOp($2, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
448     }
449     ;
450
451 AdditiveExpr:
452     MultiplicativeExpr
453     |
454     AdditiveExpr PLUS MultiplicativeExpr
455     {
456         $$ = new NumericOp(NumericOp::OP_Add, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
457     }
458     |
459     AdditiveExpr MINUS MultiplicativeExpr
460     {
461         $$ = new NumericOp(NumericOp::OP_Sub, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
462     }
463     ;
464
465 MultiplicativeExpr:
466     UnaryExpr
467     |
468     MultiplicativeExpr MULOP UnaryExpr
469     {
470         $$ = new NumericOp($2, std::unique_ptr<Expression>($1), std::unique_ptr<Expression>($3));
471     }
472     ;
473
474 UnaryExpr:
475     UnionExpr
476     |
477     MINUS UnaryExpr
478     {
479         $$ = new Negative(std::unique_ptr<Expression>($2));
480     }
481     ;
482
483 %%