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