2 * XSLPattern parser (XSLPattern => XPath)
4 * Copyright 2010 Adam Martinson for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
26 #include "xslpattern.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
31 static const xmlChar NameTest_mod_pre[] = "*[namespace-uri()=namespace::*[local-name()=''] or namespace-uri()=''][local-name()='";
32 static const xmlChar NameTest_mod_post[] = "']";
34 #define U(str) BAD_CAST str
35 #define DBG(str) wine_dbgstr_a((char const*)str)
38 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
39 %token TOK_OpAnd TOK_OpOr TOK_OpNot
40 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
41 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
42 %token TOK_OpAll TOK_OpAny
43 %token TOK_NCName TOK_Literal TOK_Number
48 %parse-param {parser_param* p}
49 %parse-param {void* scanner}
50 %lex-param {yyscan_t* scanner}
52 %left TOK_OpAnd TOK_OpOr
53 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
54 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
64 /* Mostly verbatim from the w3c XML Namespaces standard.
65 * <http://www.w3.org/TR/REC-xml-names/> */
67 /* [4] Qualified Names */
71 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
73 TRACE("Got PrefixedName: %s:%s\n", DBG($1), DBG($3));
75 $$=xmlStrcat($$, U(":"));
80 UnprefixedName : TOK_NCName
82 TRACE("Got UnprefixedName: %s\n", DBG($1));
87 /* Based on the w3c XPath standard, adapted where needed.
88 * <http://www.w3.org/TR/xpath/> */
90 /* [2] Location Paths */
91 LocationPath : RelativeLocationPath
92 | AbsoluteLocationPath
94 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
96 TRACE("Got AbsoluteLocationPath: /%s\n", DBG($1));
103 TRACE("Got AbsoluteLocationPath: /\n");
104 $$=xmlStrdup(U("/"));
106 | AbbreviatedAbsoluteLocationPath
108 RelativeLocationPath : Step
109 | RelativeLocationPath TOK_FSlash Step
111 TRACE("Got RelativeLocationPath: %s/%s\n", DBG($1), DBG($3));
113 $$=xmlStrcat($$,U("/"));
117 | AbbreviatedRelativeLocationPath
119 /* [2.1] Location Steps */
120 Step : AxisSpecifier NameTest Predicates
122 TRACE("Got Step: %s%s%s\n", DBG($1), DBG($2), DBG($3));
129 | NameTest Predicates
131 TRACE("Got Step: %s%s\n", DBG($1), DBG($2));
136 | AxisSpecifier NameTest
138 TRACE("Got Step: %s%s\n", DBG($1), DBG($2));
147 AxisSpecifier : TOK_NCName TOK_Axis
149 TRACE("Got AxisSpecifier: %s::\n", DBG($1));
151 $$=xmlStrcat($$,U("::"));
154 Attribute : '@' TOK_NCName
156 TRACE("Got Attribute: @%s\n", DBG($2));
157 $$=xmlStrdup(U("@"));
163 /* [2.3] Node Tests */
166 TRACE("Got NameTest: *\n");
167 $$=xmlStrdup(U("*"));
169 | TOK_NCName TOK_Colon '*'
171 TRACE("Got NameTest: %s:*\n", DBG($1));
173 $$=xmlStrcat($$,U(":*"));
178 $$=xmlStrdup(NameTest_mod_pre);
181 $$=xmlStrcat($$,NameTest_mod_post);
183 /* [2.4] Predicates */
184 Predicates : Predicates Predicate
192 Predicate : '[' PredicateExpr ']'
194 TRACE("Got Predicate: [%s]\n", DBG($2));
195 $$=xmlStrdup(U("["));
198 $$=xmlStrcat($$,U("]"));
201 PredicateExpr : TOK_Number
203 $$=xmlStrdup(U("index()="));
210 /* [2.5] Abbreviated Syntax */
211 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
213 TRACE("Got AbbreviatedAbsoluteLocationPath: //%s\n", DBG($2));
214 $$=xmlStrdup(U("//"));
219 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
221 TRACE("Got AbbreviatedRelativeLocationPath: %s//%s\n", DBG($1), DBG($2));
223 $$=xmlStrcat($$,U("//"));
228 AbbreviatedStep : TOK_Parent
230 TRACE("Got AbbreviatedStep: ..\n");
231 $$=xmlStrdup(U(".."));
235 TRACE("Got AbbreviatedStep: .\n");
236 $$=xmlStrdup(U("."));
240 /* [3] Expressions */
244 BoolExpr : FunctionCall
251 PrimaryExpr : '(' Expr ')'
253 TRACE("Got PrimaryExpr: (%s)\n", DBG($1));
254 $$=xmlStrdup(U("("));
257 $$=xmlStrcat($$,U(")"));
259 | PathExpr '!' FunctionCall
261 TRACE("Got PrimaryExpr: %s!%s\n", DBG($1), DBG($3));
263 $$=xmlStrcat($$,U("/"));
271 /* [3.2] Function Calls */
272 FunctionCall : QName '(' Arguments ')'
274 TRACE("Got FunctionCall: %s(%s)\n", DBG($1), DBG($3));
276 $$=xmlStrcat($$,U("("));
279 $$=xmlStrcat($$,U(")"));
283 TRACE("Got FunctionCall: %s()\n", DBG($1));
285 $$=xmlStrcat($$,U("()"));
288 Arguments : Argument ',' Arguments
291 $$=xmlStrcat($$,U(","));
299 /* [3.3] Node-sets */
301 | UnionExpr '|' PathExpr
303 TRACE("Got UnionExpr: %s|%s\n", DBG($1), DBG($3));
305 $$=xmlStrcat($$,U("|"));
310 PathExpr : LocationPath
311 | FilterExpr TOK_FSlash RelativeLocationPath
313 TRACE("Got PathExpr: %s/%s\n", DBG($1), DBG($3));
315 $$=xmlStrcat($$,U("/"));
319 | FilterExpr TOK_DblFSlash RelativeLocationPath
321 TRACE("Got PathExpr: %s//%s\n", DBG($1), DBG($3));
323 $$=xmlStrcat($$,U("//"));
329 FilterExpr : PrimaryExpr
330 | FilterExpr Predicate
332 TRACE("Got FilterExpr: %s%s\n", DBG($1), DBG($2));
342 BoolOrExpr : OrExpr TOK_OpOr AndExpr
344 TRACE("Got OrExpr: %s or %s\n", DBG($1), DBG($3));
346 $$=xmlStrcat($$,U(" or "));
351 AndExpr : EqualityExpr
354 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
356 TRACE("Got AndExpr: %s and %s\n", DBG($1), DBG($3));
358 $$=xmlStrcat($$,U(" and "));
363 EqualityExpr : RelationalExpr
366 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
368 TRACE("Got EqualityExpr: %s $eq$ %s\n", DBG($1), DBG($3));
370 $$=xmlStrcat($$,U("="));
374 | EqualityExpr TOK_OpIEq RelationalExpr
376 TRACE("Got EqualityExpr: %s $ieq$ %s\n", DBG($1), DBG($3));
377 $$=xmlStrdup(U("OP_IEq("));
380 $$=xmlStrcat($$,U(","));
383 $$=xmlStrcat($$,U(")"));
385 | EqualityExpr TOK_OpNEq RelationalExpr
387 TRACE("Got EqualityExpr: %s $ne$ %s\n", DBG($1), DBG($3));
389 $$=xmlStrcat($$,U("!="));
393 | EqualityExpr TOK_OpINEq RelationalExpr
395 TRACE("Got EqualityExpr: %s $ine$ %s\n", DBG($1), DBG($3));
396 $$=xmlStrdup(U("OP_INEq("));
399 $$=xmlStrcat($$,U(","));
402 $$=xmlStrcat($$,U(")"));
405 RelationalExpr : UnaryExpr
408 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
410 TRACE("Got RelationalExpr: %s $lt$ %s\n", DBG($1), DBG($3));
412 $$=xmlStrcat($$,U("<"));
416 | RelationalExpr TOK_OpILt UnaryExpr
418 TRACE("Got RelationalExpr: %s $ilt$ %s\n", DBG($1), DBG($3));
419 $$=xmlStrdup(U("OP_ILt("));
422 $$=xmlStrcat($$,U(","));
425 $$=xmlStrcat($$,U(")"));
427 | RelationalExpr TOK_OpGt UnaryExpr
429 TRACE("Got RelationalExpr: %s $gt$ %s\n", DBG($1), DBG($3));
431 $$=xmlStrcat($$,U(">"));
435 | RelationalExpr TOK_OpIGt UnaryExpr
437 TRACE("Got RelationalExpr: %s $igt$ %s\n", DBG($1), DBG($3));
438 $$=xmlStrdup(U("OP_IGt("));
441 $$=xmlStrcat($$,U(","));
444 $$=xmlStrcat($$,U(")"));
446 | RelationalExpr TOK_OpLEq UnaryExpr
448 TRACE("Got RelationalExpr: %s $le$ %s\n", DBG($1), DBG($3));
450 $$=xmlStrcat($$,U("<="));
454 | RelationalExpr TOK_OpILEq UnaryExpr
456 TRACE("Got RelationalExpr: %s $ile$ %s\n", DBG($1), DBG($3));
457 $$=xmlStrdup(U("OP_ILEq("));
460 $$=xmlStrcat($$,U(","));
463 $$=xmlStrcat($$,U(")"));
465 | RelationalExpr TOK_OpGEq UnaryExpr
467 TRACE("Got RelationalExpr: %s $ge$ %s\n", DBG($1), DBG($3));
469 $$=xmlStrcat($$,U(">="));
473 | RelationalExpr TOK_OpIGEq UnaryExpr
475 TRACE("Got RelationalExpr: %s $ige$ %s\n", DBG($1), DBG($3));
476 $$=xmlStrdup(U("OP_IGEq("));
479 $$=xmlStrcat($$,U(","));
482 $$=xmlStrcat($$,U(")"));
487 UnaryExpr : UnionExpr
490 BoolUnaryExpr : TOK_OpNot UnaryExpr
492 TRACE("Got UnaryExpr: $not$ %s\n", DBG($2));
493 $$=xmlStrdup(U(" not("));
496 $$=xmlStrcat($$,U(")"));
500 TRACE("Got UnaryExpr: $any$ %s\n", DBG($2));
501 $$=xmlStrdup(U("boolean("));
504 $$=xmlStrcat($$,U(")"));
508 TRACE("Got UnaryExpr: $all$ %s\n", DBG($2));
509 $$=xmlStrdup(U("not("));
512 $$=xmlStrcat($$,U(")"));
516 FIXME("Unrecognized $all$ expression - ignoring\n");
520 AllExpr : PathExpr TOK_OpEq PathExpr
523 $$=xmlStrcat($$,U("!="));
527 | PathExpr TOK_OpNEq PathExpr
530 $$=xmlStrcat($$,U("="));
534 | PathExpr TOK_OpLt PathExpr
537 $$=xmlStrcat($$,U(">="));
541 | PathExpr TOK_OpLEq PathExpr
544 $$=xmlStrcat($$,U(">"));
548 | PathExpr TOK_OpGt PathExpr
551 $$=xmlStrcat($$,U("<="));
555 | PathExpr TOK_OpGEq PathExpr
558 $$=xmlStrcat($$,U("<"));
562 | PathExpr TOK_OpIEq PathExpr
564 $$=xmlStrdup(U("OP_INEq("));
567 $$=xmlStrcat($$,U(","));
570 $$=xmlStrcat($$,U(")"));
572 | PathExpr TOK_OpINEq PathExpr
574 $$=xmlStrdup(U("OP_IEq("));
577 $$=xmlStrcat($$,U(","));
580 $$=xmlStrcat($$,U(")"));
582 | PathExpr TOK_OpILt PathExpr
584 $$=xmlStrdup(U("OP_IGEq("));
587 $$=xmlStrcat($$,U(","));
590 $$=xmlStrcat($$,U(")"));
592 | PathExpr TOK_OpILEq PathExpr
594 $$=xmlStrdup(U("OP_IGt("));
597 $$=xmlStrcat($$,U(","));
600 $$=xmlStrcat($$,U(")"));
602 | PathExpr TOK_OpIGt PathExpr
604 $$=xmlStrdup(U("OP_ILEq("));
607 $$=xmlStrcat($$,U(","));
610 $$=xmlStrcat($$,U(")"));
612 | PathExpr TOK_OpIGEq PathExpr
614 $$=xmlStrdup(U("OP_ILt("));
617 $$=xmlStrcat($$,U(","));
620 $$=xmlStrcat($$,U(")"));
626 void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
638 msg, param->yyscanner, param->in, param->pos, param->len,
639 param->out, ++param->err, scanner);
643 #endif /* HAVE_LIBXML2 */