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