| /* | |
| * XSLPattern lexer | |
| * | |
| * Copyright 2010 Adam Martinson for CodeWeavers | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| %{ | |
| #include "config.h" | |
| #include "wine/port.h" | |
| #ifdef HAVE_LIBXML2 | |
| #include "xslpattern.h" | |
| #include "xslpattern.tab.h" | |
| #include "wine/debug.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(msxml); | |
| #define SCAN xslpattern_get_extra(yyscanner) | |
| #define YY_INPUT(tok_buf, tok_len, max) \ | |
| do { \ | |
| if (SCAN->pos <= SCAN->len) \ | |
| { \ | |
| tok_len = SCAN->len - SCAN->pos; \ | |
| if (tok_len > max) tok_len = max; \ | |
| memcpy(tok_buf, SCAN->in + SCAN->pos, tok_len); \ | |
| SCAN->pos += tok_len; \ | |
| } \ | |
| else \ | |
| { \ | |
| tok_len = YY_NULL; \ | |
| } \ | |
| } while (0); | |
| #define TOK(tok) TRACE("token: %s : %s\n", #tok, yytext); return tok | |
| #define OP(tok) *yylval=NULL; TOK(tok) | |
| #define SYM(tok) *yylval=NULL; TOK(tok) | |
| #define STR(tok) *yylval=xmlStrdup(BAD_CAST yytext); TOK(tok) | |
| %} | |
| %option reentrant bison-bridge | |
| %option noyywrap | |
| %option prefix="xslpattern_" | |
| %option noinput nounput never-interactive | |
| /* From the w3c XML standard | |
| * <http://www.w3.org/TR/REC-xml/> */ | |
| /* [2.3] Common Syntactic Constructs */ | |
| WSpace ([[:space:]]) | |
| NCNameStartChar ([A-Za-z_]|[\xc0-\xd6\xd8-\xf6\xf8-\xff]) | |
| NameCharEx ([0-9]|[-._\xb7]) | |
| NCNameChar ({NCNameStartChar}|{NameCharEx}) | |
| /* From the w3c XML Namespace standard | |
| * <http://www.w3.org/TR/REC-xml-names/> */ | |
| /* [3] Declaring Namespaces*/ | |
| NCName ({NCNameStartChar}{NCNameChar}*) | |
| /* Mostly verbatim from the w3c XPath standard. | |
| * <http://www.w3.org/TR/xpath/> */ | |
| /* [3.4] Booleans | |
| * ||, &&, $foo$ are XSLPattern only */ | |
| OP_Or ("or"|"||"|"$or$") | |
| OP_And ("and"|"&&"|"$and$") | |
| OP_Eq ("="|"$eq$") | |
| OP_IEq ("$ieq$") | |
| OP_NEq ("!="|"$ne$") | |
| OP_INEq ("$ine$") | |
| OP_Lt ("<"|"$lt$") | |
| OP_ILt ("$ilt$") | |
| OP_Gt (">"|"$gt$") | |
| OP_IGt ("$igt$") | |
| OP_LEq ("<="|"$le$") | |
| OP_ILEq ("$ile$") | |
| OP_GEq (">="|"$ge$") | |
| OP_IGEq ("$ige$") | |
| OP_Not ("$not$") | |
| OP_All ("$all$") | |
| OP_Any ("$any$") | |
| /* [3.7] Lexical Structure */ | |
| Literal (([\x22]([^\x22]*)[\x22])|([\x27]([^\x27]*)[\x27])) | |
| Number ({Digits}("."{Digits}?)?|"."{Digits}) | |
| Digits ([0-9]+) | |
| ANY (.) | |
| %% | |
| {WSpace}+ { /* ignored */ } | |
| {Literal} { STR(TOK_Literal); } | |
| "//" { SYM(TOK_DblFSlash); } | |
| "/" { SYM(TOK_FSlash); } | |
| ".." { SYM(TOK_Parent); } | |
| "." { SYM(TOK_Self); } | |
| "::" { SYM(TOK_Axis); } | |
| ":" { SYM(TOK_Colon); } | |
| "(" { SYM('('); } | |
| ")" { SYM(')'); } | |
| "[" { SYM('['); } | |
| "]" { SYM(']'); } | |
| "@" { SYM('@'); } | |
| "," { SYM(','); } | |
| "*" { SYM('*'); } | |
| {OP_And} { OP(TOK_OpAnd); } | |
| {OP_Or} { OP(TOK_OpOr); } | |
| {OP_Not} { OP(TOK_OpNot); } | |
| {OP_Eq} { OP(TOK_OpEq); } | |
| {OP_IEq} { OP(TOK_OpIEq); } | |
| {OP_NEq} { OP(TOK_OpNEq); } | |
| {OP_INEq} { OP(TOK_OpINEq); } | |
| {OP_Lt} { OP(TOK_OpLt); } | |
| {OP_ILt} { OP(TOK_OpILt); } | |
| {OP_Gt} { OP(TOK_OpGt); } | |
| {OP_IGt} { OP(TOK_OpIGt); } | |
| {OP_LEq} { OP(TOK_OpLEq); } | |
| {OP_ILEq} { OP(TOK_OpILEq); } | |
| {OP_GEq} { OP(TOK_OpGEq); } | |
| {OP_IGEq} { OP(TOK_OpIGEq); } | |
| {OP_All} { OP(TOK_OpAll); } | |
| {OP_Any} { OP(TOK_OpAny); } | |
| "|" { SYM('|'); } | |
| "!" { SYM('!'); } | |
| {NCName} { STR(TOK_NCName); } | |
| {Number} { STR(TOK_Number); } | |
| {ANY} { FIXME("Unexpected character '%s'.\n",yytext); } | |
| %% | |
| xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr, xmlChar const*) DECLSPEC_HIDDEN; | |
| xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str) | |
| { | |
| parser_param p; | |
| TRACE("(%s)\n", debugstr_a((char const*)xslpat_str)); | |
| memset(&p, 0, sizeof(parser_param)); | |
| p.ctx = ctxt; | |
| p.in = xslpat_str; | |
| p.len = xmlStrlen(xslpat_str); | |
| xslpattern_lex_init(&p.yyscanner); | |
| xslpattern_set_extra(&p, p.yyscanner); | |
| xslpattern_parse(&p, p.yyscanner); | |
| TRACE("=> %s\n", debugstr_a((char const*)p.out)); | |
| xslpattern_lex_destroy(p.yyscanner); | |
| if (p.err) | |
| { | |
| xmlFree(p.out); | |
| return xmlStrdup(xslpat_str); | |
| } | |
| else | |
| { | |
| return p.out; | |
| } | |
| } | |
| #endif /* HAVE_LIBXML2 */ |