2641ebe2e5c4d9105b296469a5b13840b80e2011
[WebKit-https.git] / WebCore / xml / XPathGrammar.y
1 /*
2  * Copyright 2005 Frerich Raabe <raabe@kde.org>
3  * Copyright (C) 2006 Apple Computer, Inc.
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 "XPathVariableReference.h"
40
41 #define YYENABLE_NLS 0
42 #define YYLTYPE_IS_TRIVIAL 1
43 #define YYDEBUG 0
44 #define YYMAXDEPTH 10000
45 #define YYPARSE_PARAM parserParameter
46 #define PARSER static_cast<Parser*>(parserParameter)
47
48 using namespace WebCore;
49 using namespace XPath;
50
51 %}
52
53 %pure_parser
54
55 %union
56 {
57     Step::Axis axis;
58     NumericOp::Opcode numop;
59     EqTestOp::Opcode eqop;
60     String* str;
61     Expression* expr;
62     Vector<Predicate*>* predList;
63     Vector<Expression*>* argList;
64     Step* step;
65     LocationPath* locationPath;
66 }
67
68 %{
69
70 int xpathyylex(YYSTYPE *yylval) { return Parser::current()->lex(yylval); }
71 void xpathyyerror(const char *str) { }
72     
73 %}
74
75 %left <numop> MULOP RELOP
76 %left <eqop> EQOP
77 %left PLUS MINUS
78 %left OR AND
79 %token <axis> AXISNAME
80 %token <str> NODETYPE PI FUNCTIONNAME LITERAL
81 %token <str> VARIABLEREFERENCE NUMBER
82 %token DOTDOT SLASHSLASH
83 %token <str> NAMETEST
84 %token ERROR
85
86 %type <locationPath> LocationPath
87 %type <locationPath> AbsoluteLocationPath
88 %type <locationPath> RelativeLocationPath
89 %type <step> Step
90 %type <axis> AxisSpecifier
91 %type <step> DescendantOrSelf
92 %type <str> NodeTest
93 %type <expr> Predicate
94 %type <predList> OptionalPredicateList
95 %type <predList> PredicateList
96 %type <step> AbbreviatedStep
97 %type <expr> Expr
98 %type <expr> PrimaryExpr
99 %type <expr> FunctionCall
100 %type <argList> ArgumentList
101 %type <expr> Argument
102 %type <expr> UnionExpr
103 %type <expr> PathExpr
104 %type <expr> FilterExpr
105 %type <expr> OrExpr
106 %type <expr> AndExpr
107 %type <expr> EqualityExpr
108 %type <expr> RelationalExpr
109 %type <expr> AdditiveExpr
110 %type <expr> MultiplicativeExpr
111 %type <expr> UnaryExpr
112
113 %%
114
115 Expr:
116     OrExpr
117     {
118         PARSER->m_topExpr = $1;
119     }
120     ;
121
122 LocationPath:
123     RelativeLocationPath
124     {
125         $$->m_absolute = false;
126     }
127     |
128     AbsoluteLocationPath
129     {
130         $$->m_absolute = true;
131     }
132     ;
133
134 AbsoluteLocationPath:
135     '/'
136     {
137         $$ = new LocationPath;
138         PARSER->registerParseNode($$);
139     }
140     |
141     '/' RelativeLocationPath
142     {
143         $$ = $2;
144     }
145     |
146     DescendantOrSelf RelativeLocationPath
147     {
148         $$ = $2;
149         $$->m_steps.insert(0, $1);
150         PARSER->unregisterParseNode($1);
151     }
152     ;
153
154 RelativeLocationPath:
155     Step
156     {
157         $$ = new LocationPath;
158         $$->m_steps.append($1);
159         PARSER->unregisterParseNode($1);
160         PARSER->registerParseNode($$);
161     }
162     |
163     RelativeLocationPath '/' Step
164     {
165         $$->m_steps.append($3);
166         PARSER->unregisterParseNode($3);
167     }
168     |
169     RelativeLocationPath DescendantOrSelf Step
170     {
171         $$->m_steps.append($2);
172         $$->m_steps.append($3);
173         PARSER->unregisterParseNode($2);
174         PARSER->unregisterParseNode($3);
175     }
176     ;
177
178 Step:
179     NodeTest OptionalPredicateList
180     {
181         if ($2) {
182             $$ = new Step(Step::ChildAxis, *$1, *$2);
183             PARSER->deletePredicateVector($2);
184         } else
185             $$ = new Step(Step::ChildAxis, *$1);
186         PARSER->deleteString($1);
187         PARSER->registerParseNode($$);
188     }
189     |
190     NAMETEST OptionalPredicateList
191     {
192         String localName;
193         String namespaceURI;
194         if (!PARSER->expandQName(*$1, localName, namespaceURI)) {
195             PARSER->m_gotNamespaceError = true;
196             YYABORT;
197         }
198         
199         if ($2) {
200             $$ = new Step(Step::ChildAxis, localName, namespaceURI, *$2);
201             PARSER->deletePredicateVector($2);
202         } else
203             $$ = new Step(Step::ChildAxis, localName, namespaceURI);
204         PARSER->deleteString($1);
205         PARSER->registerParseNode($$);
206     }
207     |
208     AxisSpecifier NodeTest OptionalPredicateList
209     {
210         if ($3) {
211             $$ = new Step($1, *$2, *$3);
212             PARSER->deletePredicateVector($3);
213         } else
214             $$ = new Step($1, *$2);
215         PARSER->deleteString($2);
216         PARSER->registerParseNode($$);
217     }
218     |
219     AxisSpecifier NAMETEST OptionalPredicateList
220     {
221         String localName;
222         String namespaceURI;
223         if (!PARSER->expandQName(*$2, localName, namespaceURI)) {
224             PARSER->m_gotNamespaceError = true;
225             YYABORT;
226         }
227
228         if ($3) {
229             $$ = new Step($1, localName, namespaceURI, *$3);
230             PARSER->deletePredicateVector($3);
231         } else
232             $$ = new Step($1, localName, namespaceURI);
233         PARSER->deleteString($2);
234         PARSER->registerParseNode($$);
235     }
236     |
237     AbbreviatedStep
238     ;
239
240 AxisSpecifier:
241     AXISNAME
242     |
243     '@'
244     {
245         $$ = Step::AttributeAxis;
246     }
247     ;
248
249 NodeTest:
250     NODETYPE '(' ')'
251     {
252         $$ = new String(*$1 + "()");
253         PARSER->deleteString($1);
254         PARSER->registerString($$);
255     }
256     |
257     PI '(' ')'
258     |
259     PI '(' LITERAL ')'
260     {
261         String s = *$1 + " " + *$3;
262         $$ = new String(s.stripWhiteSpace());
263         PARSER->deleteString($1);        
264         PARSER->deleteString($3);
265         PARSER->registerString($$);
266     }
267     ;
268
269 OptionalPredicateList:
270     /* empty */
271     {
272         $$ = 0;
273     }
274     |
275     PredicateList
276     ;
277
278 PredicateList:
279     Predicate
280     {
281         $$ = new Vector<Predicate*>;
282         $$->append(new Predicate($1));
283         PARSER->unregisterParseNode($1);
284         PARSER->registerPredicateVector($$);
285     }
286     |
287     PredicateList Predicate
288     {
289         $$->append(new Predicate($2));
290         PARSER->unregisterParseNode($2);
291     }
292     ;
293
294 Predicate:
295     '[' Expr ']'
296     {
297         $$ = $2;
298     }
299     ;
300
301 DescendantOrSelf:
302     SLASHSLASH
303     {
304         $$ = new Step(Step::DescendantOrSelfAxis, "node()");
305         PARSER->registerParseNode($$);
306     }
307     ;
308
309 AbbreviatedStep:
310     '.'
311     {
312         $$ = new Step(Step::SelfAxis, "node()");
313         PARSER->registerParseNode($$);
314     }
315     |
316     DOTDOT
317     {
318         $$ = new Step(Step::ParentAxis, "node()");
319         PARSER->registerParseNode($$);
320     }
321     ;
322
323 PrimaryExpr:
324     VARIABLEREFERENCE
325     {
326         $$ = new VariableReference(*$1);
327         PARSER->deleteString($1);
328         PARSER->registerParseNode($$);
329     }
330     |
331     '(' Expr ')'
332     {
333         $$ = $2;
334     }
335     |
336     LITERAL
337     {
338         $$ = new StringExpression(*$1);
339         PARSER->deleteString($1);
340         PARSER->registerParseNode($$);
341     }
342     |
343     NUMBER
344     {
345         $$ = new Number($1->toDouble());
346         PARSER->deleteString($1);
347         PARSER->registerParseNode($$);
348     }
349     |
350     FunctionCall
351     ;
352
353 FunctionCall:
354     FUNCTIONNAME '(' ')'
355     {
356         $$ = createFunction(*$1);
357         PARSER->deleteString($1);
358         PARSER->registerParseNode($$);
359     }
360     |
361     FUNCTIONNAME '(' ArgumentList ')'
362     {
363         $$ = createFunction(*$1, *$3);
364         PARSER->deleteString($1);
365         PARSER->deleteExpressionVector($3);
366         PARSER->registerParseNode($$);
367     }
368     ;
369
370 ArgumentList:
371     Argument
372     {
373         $$ = new Vector<Expression*>;
374         $$->append($1);
375         PARSER->unregisterParseNode($1);
376         PARSER->registerExpressionVector($$);
377     }
378     |
379     ArgumentList ',' Argument
380     {
381         $$->append($3);
382         PARSER->unregisterParseNode($3);
383     }
384     ;
385
386 Argument:
387     Expr
388     ;
389
390 UnionExpr:
391     PathExpr
392     |
393     UnionExpr '|' PathExpr
394     {
395         $$ = new Union;
396         $$->addSubExpression($1);
397         $$->addSubExpression($3);
398         PARSER->unregisterParseNode($1);
399         PARSER->unregisterParseNode($3);
400         PARSER->registerParseNode($$);
401     }
402     ;
403
404 PathExpr:
405     LocationPath
406     {
407         $$ = $1;
408     }
409     |
410     FilterExpr
411     |
412     FilterExpr '/' RelativeLocationPath
413     {
414         $3->m_absolute = true;
415         $$ = new Path(static_cast<Filter*>($1), $3);
416         PARSER->unregisterParseNode($1);
417         PARSER->unregisterParseNode($3);
418         PARSER->registerParseNode($$);
419     }
420     |
421     FilterExpr DescendantOrSelf RelativeLocationPath
422     {
423         $3->m_steps.insert(0, $2);
424         $3->m_absolute = true;
425         $$ = new Path(static_cast<Filter*>($1), $3);
426         PARSER->unregisterParseNode($1);
427         PARSER->unregisterParseNode($2);
428         PARSER->unregisterParseNode($3);
429         PARSER->registerParseNode($$);
430     }
431     ;
432
433 FilterExpr:
434     PrimaryExpr
435     |
436     PrimaryExpr PredicateList
437     {
438         $$ = new Filter($1, *$2);
439         PARSER->unregisterParseNode($1);
440         PARSER->deletePredicateVector($2);
441         PARSER->registerParseNode($$);
442     }
443     ;
444
445 OrExpr:
446     AndExpr
447     |
448     OrExpr OR AndExpr
449     {
450         $$ = new LogicalOp(LogicalOp::OP_Or, $1, $3);
451         PARSER->unregisterParseNode($1);
452         PARSER->unregisterParseNode($3);
453         PARSER->registerParseNode($$);
454     }
455     ;
456
457 AndExpr:
458     EqualityExpr
459     |
460     AndExpr AND EqualityExpr
461     {
462         $$ = new LogicalOp(LogicalOp::OP_And, $1, $3);
463         PARSER->unregisterParseNode($1);
464         PARSER->unregisterParseNode($3);
465         PARSER->registerParseNode($$);
466     }
467     ;
468
469 EqualityExpr:
470     RelationalExpr
471     |
472     EqualityExpr EQOP RelationalExpr
473     {
474         $$ = new EqTestOp($2, $1, $3);
475         PARSER->unregisterParseNode($1);
476         PARSER->unregisterParseNode($3);
477         PARSER->registerParseNode($$);
478     }
479     ;
480
481 RelationalExpr:
482     AdditiveExpr
483     |
484     RelationalExpr RELOP AdditiveExpr
485     {
486         $$ = new NumericOp($2, $1, $3);
487         PARSER->unregisterParseNode($1);
488         PARSER->unregisterParseNode($3);
489         PARSER->registerParseNode($$);
490     }
491     ;
492
493 AdditiveExpr:
494     MultiplicativeExpr
495     |
496     AdditiveExpr PLUS MultiplicativeExpr
497     {
498         $$ = new NumericOp(NumericOp::OP_Add, $1, $3);
499         PARSER->unregisterParseNode($1);
500         PARSER->unregisterParseNode($3);
501         PARSER->registerParseNode($$);
502     }
503     |
504     AdditiveExpr MINUS MultiplicativeExpr
505     {
506         $$ = new NumericOp(NumericOp::OP_Sub, $1, $3);
507         PARSER->unregisterParseNode($1);
508         PARSER->unregisterParseNode($3);
509         PARSER->registerParseNode($$);
510     }
511     ;
512
513 MultiplicativeExpr:
514     UnaryExpr
515     |
516     MultiplicativeExpr MULOP UnaryExpr
517     {
518         $$ = new NumericOp($2, $1, $3);
519         PARSER->unregisterParseNode($1);
520         PARSER->unregisterParseNode($3);
521         PARSER->registerParseNode($$);
522     }
523     ;
524
525 UnaryExpr:
526     UnionExpr
527     |
528     MINUS UnaryExpr
529     {
530         $$ = new Negative;
531         $$->addSubExpression($2);
532         PARSER->unregisterParseNode($2);
533         PARSER->registerParseNode($$);
534     }
535     ;
536
537 %%
538
539 #endif