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"
27 #include <libxml/xpathInternals.h>
29 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
32 static const xmlChar NameTest_mod_pre[] = "*[name()='";
33 static const xmlChar NameTest_mod_post[] = "']";
35 #define U(str) BAD_CAST str
39 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
40 %token TOK_OpAnd TOK_OpOr TOK_OpNot
41 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
42 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
43 %token TOK_OpAll TOK_OpAny
44 %token TOK_NCName TOK_Literal TOK_Number
49 %parse-param {parser_param* p}
50 %parse-param {void* scanner}
51 %lex-param {yyscan_t* scanner}
53 %left TOK_OpAnd TOK_OpOr
54 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
55 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
65 /* Mostly verbatim from the w3c XML Namespaces standard.
66 * <http://www.w3.org/TR/REC-xml-names/> */
68 /* [4] Qualified Names */
72 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
74 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
76 $$=xmlStrcat($$,U(":"));
81 UnprefixedName : TOK_NCName
83 TRACE("Got UnprefixedName: \"%s\"\n", $1);
88 /* Based on the w3c XPath standard, adapted where needed.
89 * <http://www.w3.org/TR/xpath/> */
91 /* [2] Location Paths */
92 LocationPath : RelativeLocationPath
93 | AbsoluteLocationPath
95 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
97 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
104 TRACE("Got AbsoluteLocationPath: \"/\"\n");
105 $$=xmlStrdup(U("/"));
107 | AbbreviatedAbsoluteLocationPath
109 RelativeLocationPath : Step
110 | RelativeLocationPath TOK_FSlash Step
112 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
114 $$=xmlStrcat($$,U("/"));
118 | AbbreviatedRelativeLocationPath
120 /* [2.1] Location Steps */
121 Step : AxisSpecifier NameTest Predicates
123 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
130 | NameTest Predicates
132 TRACE("Got Step: \"%s%s\"\n", $1, $2);
137 | AxisSpecifier NameTest
139 TRACE("Got Step: \"%s%s\"\n", $1, $2);
148 AxisSpecifier : TOK_NCName TOK_Axis
150 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
152 $$=xmlStrcat($$,U("::"));
155 Attribute : '@' TOK_NCName
157 TRACE("Got Attribute: \"@%s\"\n", $2);
158 $$=xmlStrdup(U("@"));
164 /* [2.3] Node Tests */
167 TRACE("Got NameTest: \"*\"\n");
168 $$=xmlStrdup(U("*"));
170 | TOK_NCName TOK_Colon '*'
172 TRACE("Got NameTest: \"%s:*\"\n", $1);
174 $$=xmlStrcat($$,U(":*"));
176 | TOK_NCName TOK_Colon TOK_NCName
178 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
179 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
184 $$=xmlStrdup(NameTest_mod_pre);
188 $$=xmlStrcat($$,U(":"));
192 if (!registeredNsURI)
193 $$=xmlStrcat($$,NameTest_mod_post);
197 $$=xmlStrdup(NameTest_mod_pre);
200 $$=xmlStrcat($$,NameTest_mod_post);
202 /* [2.4] Predicates */
203 Predicates : Predicates Predicate
211 Predicate : '[' PredicateExpr ']'
213 TRACE("Got Predicate: \"[%s]\"\n", $2);
214 $$=xmlStrdup(U("["));
217 $$=xmlStrcat($$,U("]"));
220 PredicateExpr : TOK_Number
222 $$=xmlStrdup(U("index()="));
229 /* [2.5] Abbreviated Syntax */
230 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
232 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
233 $$=xmlStrdup(U("//"));
238 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
240 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
242 $$=xmlStrcat($$,U("//"));
247 AbbreviatedStep : TOK_Parent
249 TRACE("Got AbbreviatedStep: \"..\"\n");
250 $$=xmlStrdup(U(".."));
254 TRACE("Got AbbreviatedStep: \".\"\n");
255 $$=xmlStrdup(U("."));
259 /* [3] Expressions */
263 BoolExpr : FunctionCall
270 PrimaryExpr : '(' Expr ')'
272 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
273 $$=xmlStrdup(U("("));
276 $$=xmlStrcat($$,U(")"));
278 | PathExpr '!' FunctionCall
280 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
282 $$=xmlStrcat($$,U("/"));
290 /* [3.2] Function Calls */
291 FunctionCall : QName '(' Arguments ')'
293 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
295 $$=xmlStrcat($$,U("("));
298 $$=xmlStrcat($$,U(")"));
302 TRACE("Got FunctionCall: \"%s()\"\n", $1);
304 $$=xmlStrcat($$,U("()"));
307 Arguments : Argument ',' Arguments
310 $$=xmlStrcat($$,U(","));
318 /* [3.3] Node-sets */
320 | UnionExpr '|' PathExpr
322 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
324 $$=xmlStrcat($$,U("|"));
329 PathExpr : LocationPath
330 | FilterExpr TOK_FSlash RelativeLocationPath
332 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
334 $$=xmlStrcat($$,U("/"));
338 | FilterExpr TOK_DblFSlash RelativeLocationPath
340 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
342 $$=xmlStrcat($$,U("//"));
348 FilterExpr : PrimaryExpr
349 | FilterExpr Predicate
351 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
361 BoolOrExpr : OrExpr TOK_OpOr AndExpr
363 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
365 $$=xmlStrcat($$,U(" or "));
370 AndExpr : EqualityExpr
373 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
375 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
377 $$=xmlStrcat($$,U(" and "));
382 EqualityExpr : RelationalExpr
385 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
387 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
389 $$=xmlStrcat($$,U("="));
393 | EqualityExpr TOK_OpIEq RelationalExpr
395 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
396 $$=xmlStrdup(U("OP_IEq("));
399 $$=xmlStrcat($$,U(","));
402 $$=xmlStrcat($$,U(")"));
404 | EqualityExpr TOK_OpNEq RelationalExpr
406 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
408 $$=xmlStrcat($$,U("!="));
412 | EqualityExpr TOK_OpINEq RelationalExpr
414 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
415 $$=xmlStrdup(U("OP_INEq("));
418 $$=xmlStrcat($$,U(","));
421 $$=xmlStrcat($$,U(")"));
424 RelationalExpr : UnaryExpr
427 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
429 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
431 $$=xmlStrcat($$,U("<"));
435 | RelationalExpr TOK_OpILt UnaryExpr
437 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
438 $$=xmlStrdup(U("OP_ILt("));
441 $$=xmlStrcat($$,U(","));
444 $$=xmlStrcat($$,U(")"));
446 | RelationalExpr TOK_OpGt UnaryExpr
448 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
450 $$=xmlStrcat($$,U(">"));
454 | RelationalExpr TOK_OpIGt UnaryExpr
456 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
457 $$=xmlStrdup(U("OP_IGt("));
460 $$=xmlStrcat($$,U(","));
463 $$=xmlStrcat($$,U(")"));
465 | RelationalExpr TOK_OpLEq UnaryExpr
467 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
469 $$=xmlStrcat($$,U("<="));
473 | RelationalExpr TOK_OpILEq UnaryExpr
475 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
476 $$=xmlStrdup(U("OP_ILEq("));
479 $$=xmlStrcat($$,U(","));
482 $$=xmlStrcat($$,U(")"));
484 | RelationalExpr TOK_OpGEq UnaryExpr
486 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
488 $$=xmlStrcat($$,U(">="));
492 | RelationalExpr TOK_OpIGEq UnaryExpr
494 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
495 $$=xmlStrdup(U("OP_IGEq("));
498 $$=xmlStrcat($$,U(","));
501 $$=xmlStrcat($$,U(")"));
506 UnaryExpr : UnionExpr
509 BoolUnaryExpr : TOK_OpNot UnaryExpr
511 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
512 $$=xmlStrdup(U(" not("));
515 $$=xmlStrcat($$,U(")"));
519 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
520 $$=xmlStrdup(U("boolean("));
523 $$=xmlStrcat($$,U(")"));
527 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
528 $$=xmlStrdup(U("not("));
531 $$=xmlStrcat($$,U(")"));
535 FIXME("Unrecognized $all$ expression - ignoring\n");
539 AllExpr : PathExpr TOK_OpEq PathExpr
542 $$=xmlStrcat($$,U("!="));
546 | PathExpr TOK_OpNEq PathExpr
549 $$=xmlStrcat($$,U("="));
553 | PathExpr TOK_OpLt PathExpr
556 $$=xmlStrcat($$,U(">="));
560 | PathExpr TOK_OpLEq PathExpr
563 $$=xmlStrcat($$,U(">"));
567 | PathExpr TOK_OpGt PathExpr
570 $$=xmlStrcat($$,U("<="));
574 | PathExpr TOK_OpGEq PathExpr
577 $$=xmlStrcat($$,U("<"));
581 | PathExpr TOK_OpIEq PathExpr
583 $$=xmlStrdup(U("OP_INEq("));
586 $$=xmlStrcat($$,U(","));
589 $$=xmlStrcat($$,U(")"));
591 | PathExpr TOK_OpINEq PathExpr
593 $$=xmlStrdup(U("OP_IEq("));
596 $$=xmlStrcat($$,U(","));
599 $$=xmlStrcat($$,U(")"));
601 | PathExpr TOK_OpILt PathExpr
603 $$=xmlStrdup(U("OP_IGEq("));
606 $$=xmlStrcat($$,U(","));
609 $$=xmlStrcat($$,U(")"));
611 | PathExpr TOK_OpILEq PathExpr
613 $$=xmlStrdup(U("OP_IGt("));
616 $$=xmlStrcat($$,U(","));
619 $$=xmlStrcat($$,U(")"));
621 | PathExpr TOK_OpIGt PathExpr
623 $$=xmlStrdup(U("OP_ILEq("));
626 $$=xmlStrcat($$,U(","));
629 $$=xmlStrcat($$,U(")"));
631 | PathExpr TOK_OpIGEq PathExpr
633 $$=xmlStrdup(U("OP_ILt("));
636 $$=xmlStrcat($$,U(","));
639 $$=xmlStrcat($$,U(")"));
645 void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
658 msg, param->yyscanner, param->ctx, param->in, param->pos,
659 param->len, param->out, ++param->err, scanner);
663 #endif /* HAVE_LIBXML2 */