File indexing completed on 2024-04-28 15:24:58
0001 /* 0002 * tokenizer_tester.cc - Copyright 2005 Frerich Raabe <raabe@kde.org> 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 0008 * 1. Redistributions of source code must retain the above copyright 0009 * notice, this list of conditions and the following disclaimer. 0010 * 2. Redistributions in binary form must reproduce the above copyright 0011 * notice, this list of conditions and the following disclaimer in the 0012 * documentation and/or other materials provided with the distribution. 0013 * 0014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0017 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 #include "expression.h" 0026 #include "step.h" // 0027 #include "path.h" // 0028 #include "predicate.h" // Order dependency. 0029 #include "parser.h" // 0030 0031 #include <QStringList> 0032 #include <QtDebug> 0033 0034 extern int xpathyylex(); 0035 extern void initTokenizer(QString s); 0036 0037 QString tokenAsString(yytokentype token) 0038 { 0039 switch (token) { 0040 case MULOP: return QString("MULOP[%1]").arg(xpathyylval.num); 0041 case MINUS: return "MINUS"; 0042 case PLUS: return "PLUS"; 0043 case RELOP: return QString("RELOP[%1]").arg(xpathyylval.num); 0044 case EQOP: return QString("EQOP[%1]").arg(xpathyylval.num); 0045 case AND: return "AND"; 0046 case OR: return "OR"; 0047 case AXISNAME: return QString("AXISNAME['%1']").arg(Step::axisAsString(xpathyylval.axisType)); 0048 case NODETYPE: return QString("NODETYPE['%1']").arg(*xpathyylval.str); 0049 case PI: return "PI"; 0050 case FUNCTIONNAME: return QString("FUNCTIONNAME['%1']").arg(*xpathyylval.str); 0051 case LITERAL: return QString("LITERAL['%1']").arg(*xpathyylval.str); 0052 case VARIABLEREFERENCE: return QString("VARIABLEREFERENCE['%1']").arg(*xpathyylval.str); 0053 case NAMETEST: return QString("NAMETEST['%1']").arg(*xpathyylval.str); 0054 case NUMBER: return QString("NUMBER['%1']").arg(*xpathyylval.str); 0055 case DOTDOT: return "DOTDOT"; 0056 case SLASHSLASH: return "SLASHSLASH"; 0057 case ERROR: return "ERROR"; 0058 } 0059 0060 return QString("'%1'").arg(char(token)); 0061 } 0062 0063 QString getTokenString(const QString &s) 0064 { 0065 initTokenizer(s); 0066 0067 QStringList tokenStrings; 0068 int token = xpathyylex(); 0069 while (token != 0) { 0070 tokenStrings << tokenAsString((yytokentype)token); 0071 token = xpathyylex(); 0072 }; 0073 0074 return tokenStrings.join(" "); 0075 } 0076 0077 void check(const QString &statement, const QString &expected) 0078 { 0079 QString result = getTokenString(statement); 0080 if (result != expected) { 0081 qCDebug(KHTML_LOG) << "ERROR: failed to tokenizer " << statement << " as expected"; 0082 qCDebug(KHTML_LOG) << "Expected: " << expected; 0083 qCDebug(KHTML_LOG) << "Got : " << result; 0084 exit(1); 0085 } 0086 } 0087 0088 int main() 0089 { 0090 check("child ::book", 0091 "AXISNAME['child'] NAMETEST['book']"); 0092 check("/this/and/that", 0093 "'/' NAMETEST['this'] '/' NAMETEST['and'] '/' NAMETEST['that']"); 0094 check("self::self/book[@and=\"and\" and true( \t\t) ]", 0095 "AXISNAME['self'] NAMETEST['self'] '/' NAMETEST['book'] '[' '@' NAMETEST['and'] EQOP[1] LITERAL['and'] AND FUNCTIONNAME['true'] '(' ')' ']'"); 0096 check("123 . .43 31. 3131.22 2.2.2", 0097 "NUMBER['123'] '.' NUMBER['.43'] NUMBER['31.'] NUMBER['3131.22'] NUMBER['2.2'] NUMBER['.2']"); 0098 check("/or/and[\"and\" and 'or\"' ]", 0099 "'/' NAMETEST['or'] '/' NAMETEST['and'] '[' LITERAL['and'] AND LITERAL['or\"'] ']'"); 0100 check("self ::node ( )[true ( )]", 0101 "AXISNAME['self'] NODETYPE['node'] '(' ')' '[' FUNCTIONNAME['true'] '(' ')' ']'"); 0102 0103 const QChar alpha(0x03B1); 0104 check(QString("self::") + alpha + alpha + alpha, 0105 QString("AXISNAME['self'] NAMETEST['") + alpha + alpha + alpha + "']"); 0106 0107 check("this[substring-after(\"Name=Joe\", \"=\" )=\"Joe\"]", 0108 "NAMETEST['this'] '[' FUNCTIONNAME['substring-after'] '(' LITERAL['Name=Joe'] ',' LITERAL['='] ')' EQOP[1] LITERAL['Joe'] ']'"); 0109 check("child::processing-instruction()", 0110 "AXISNAME['child'] PI '(' ')'"); 0111 check("child::processing-instruction(\"yadda\")", 0112 "AXISNAME['child'] PI '(' LITERAL['yadda'] ')'"); 0113 check("*", 0114 "NAMETEST['*']"); 0115 check("comment() | text() | processing-instruction() | node()", 0116 "NODETYPE['comment'] '(' ')' '|' NODETYPE['text'] '(' ')' '|' PI '(' ')' '|' NODETYPE['node'] '(' ')'"); 0117 qDebug("All OK!"); 0118 } 0119