From ddfaffe08d23e4663fe759d67ae33fd67fc9ce5b Mon Sep 17 00:00:00 2001 From: Aaron Spike Date: Wed, 12 Apr 2006 13:20:54 +0000 Subject: Removed file/folder for ishmal (bzr r478) --- src/dom/xpathparser.cpp | 1910 ----------------------------------------------- 1 file changed, 1910 deletions(-) delete mode 100755 src/dom/xpathparser.cpp (limited to 'src/dom/xpathparser.cpp') diff --git a/src/dom/xpathparser.cpp b/src/dom/xpathparser.cpp deleted file mode 100755 index a2d3dc56b..000000000 --- a/src/dom/xpathparser.cpp +++ /dev/null @@ -1,1910 +0,0 @@ -/** - * Phoebe DOM Implementation. - * - * This is a C++ approximation of the W3C DOM model, which follows - * fairly closely the specifications in the various .idl files, copies of - * which are provided for reference. Most important is this one: - * - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html - * - * Authors: - * Bob Jamison - * - * Copyright (C) 2005 Bob Jamison - * - * 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 "xpathparser.h" -#include "charclass.h" - -namespace org -{ -namespace w3c -{ -namespace dom -{ -namespace xpath -{ - - -//######################################################################### -//# M E S S A G E S -//######################################################################### - -void XPathParser::trace(const char *fmt, ...) -{ - if (!debug) - return; - - FILE *f = stdout; - - va_list args; - va_start(args, fmt); - fprintf(f, "XPathParser: "); - vfprintf(f, fmt, args); - fprintf(f, "\n"); - va_end(args); -} - -void XPathParser::error(const char *fmt, ...) -{ - FILE *f = stdout; - va_list args; - va_start(args, fmt); - fprintf(f, "XPathParser ERROR: "); - vfprintf(f, fmt, args); - fprintf(f, "\n"); - va_end(args); - - //Print location in string - fprintf(f, "%s\n", parsebuf); - for (int i=0 ; i=(int)lexicalTokens.size()) - { - LexTok tok; - return tok; - } - return lexicalTokens[p]; -} - -int XPathParser::lexTokType(int p) -{ - if (p < 0 || p>(int)lexicalTokens.size()) - return -1; - return lexicalTokens[p].getType(); -} - - - - - - - - -int XPathParser::peek(int p) -{ - if (p >= parselen) - return -1; - position = p; - return parsebuf[p] ; -} - - -int XPathParser::get(int p) -{ - if (p >= parselen) - return -1; - position = p; - return parsebuf[p]; -} - -int XPathParser::skipwhite(int p0) -{ - int p = p0; - - while (p < parselen) - { - int ch = peek(p); - if (!isWhitespace(ch)) - break; - ch = get(p++); - } - return p; -} - -int XPathParser::getword(int p0, DOMString &str) -{ - int p = p0; - while (p < parselen) - { - int ch = peek(p); - if (!isLetterOrDigit(ch)) - break; - ch = get(p++); - str.push_back(ch); - } - return p; -} - -int XPathParser::match(int p, const char *str) -{ - while (*str) - { - if (p >= parselen) - return -1; - if (parsebuf[p] != *str) - return -1; - p++; str++; - } - return p; -} - - - - -int XPathParser::getNumber(int p0, double &dresult) -{ - int p = p0; - if (p >= parselen) - return p0;/*need at least x*/ - - bool isdouble = false; - bool negative = false; - - int ch = parsebuf[p]; - if (ch=='-') - { - p++; - negative = true; - if (p >= parselen) return p0; - } - - bool seen_dot = false; - bool seen_e = false; - bool seen_eminus = false; - - DOMString num; - - int i = p; - while (i < parselen) - { - ch = parsebuf[i]; - if (ch=='.') - { - if (seen_dot) - return p0; - seen_dot = true; - isdouble = true; - } - else if (ch=='e' || ch=='E') - { - if (seen_e || !seen_dot) - return p0; - seen_e = true; - } - else if (ch=='-' && seen_e) - { - if (seen_eminus || !seen_dot) - return p0; - seen_eminus = true; - } - else if (!isDigit(ch)) - break; - num.push_back(ch); - i++; - } - - if (i == p)/*no digits*/ - return p0; - if (isdouble) - { - const char *begin = num.c_str(); - char *end; - dresult = strtod(begin,&end); - if (!end)/*not a number?*/ - { - error("Error formatting double: %s\n", num.c_str()); - return p0; - } - } - else - { - const char *begin = num.c_str(); - char *end; - dresult = (double)strtol(begin,&end,10); - if (!end)/*not a number?*/ - { - error("Error formatting integer: %s\n", num.c_str()); - return p0; - } - } - p = i; - return p; -} - -int XPathParser::getLiteral(int p0, DOMString &result) -{ - int p = p0; - int ch = peek(p); - int quotechar = 0; - if (ch == '"' || ch == '\'') - { - quotechar = ch; - } - else - return p0; - p++; - while (true) - { - if (p >= parselen) - { - error("Unterminated literal string"); - return -1; - } - ch = peek(p); - if (ch == quotechar) - break; - result.push_back(ch); - p++; - } - p++; //skip over closing " - return p; -} - - -int XPathParser::getNCName(int p0, DOMString &result) -{ - int p = p0; - int ch = peek(p); - if (ch != '_' && !isLetter(ch)) - return p0; - - result.push_back(ch); - p++; - while (p < parselen) - { - ch = peek(p); - if ( isLetterOrDigit(ch) || - isCombiningChar(ch) || - isExtender(ch) || - ch == '.' || ch == '-' || ch == '_' ) - { - result.push_back(ch); - p++; - } - else - break; - } - return p; -} - -int XPathParser::getNameTest(int p0, DOMString &result) -{ - int p = p0; - int ch = peek(p); - if (ch == '*') - { - result.push_back(ch); - p++; - return p; - } - - DOMString ncName; - int p2 = getNCName(p, ncName); - if (p2 <= p) - return p0; - - result = ncName; - p = p2; - - ch = peek(p); - if (ch != ':' )//short name. we are done - { - return p; - } - - if (peek(p+1) == ':') //was name:: which is ok - return p; - - result.push_back(':'); - - p++; - ch = peek(p); - if (ch == '*') - { - result.push_back(ch); - p++; - return p; - } - - DOMString ncName2; - p2 = getNCName(p, ncName2); - if (p2 <= p) - { - if (peek(p) == ':') //was name:: which is ok - return p0; - error("Nothing after ':' in QName"); - return -1; - } - - result.append(ncName2); - - p = p2; - - return p; -} - - - -int XPathParser::lexicalScan() -{ - lexicalTokens.clear(); - - int p = 0; - int p2 = p; - - while (p < parselen) - { - p2 = skipwhite(p); - p = p2; - - //trace("nextChar:%c", peek(p)); - bool selected = false; - - //### LITERAL EXPR TOKENS - for (int i=2 ; i<=10 ; i++) - { - p2 = match(p, exprTokenTable[i].sval); - if (p2 > p) - { - lexTokAdd(exprTokenTable[i].ival, p); - p = p2; - selected = true; - break; - } - } - if (selected) - continue; - - //### OPERATORS - for (LookupEntry *entry = operatorTable; entry->sval ; entry++) - { - p2 = match(p, entry->sval); - if (p2 > p) - { - long op = (long)entry->ival; - //according to the disambiguating rule for * in the spec - if (op == MULTIPLY && lexicalTokens.size() > 0) - { - int ltyp = lexTokType(lexicalTokens.size()-1); - if (ltyp != AMPR && ltyp != DOUBLE_COLON && - ltyp != LPAREN && ltyp != RBRACKET && - ltyp != COMMA && ltyp != OPERATOR ) - { - lexTokAdd(OPERATOR, p, (long)entry->ival); - p = p2; - selected = true; - break; - } - } - else - { - lexTokAdd(OPERATOR, p, (long)entry->ival); - p = p2; - selected = true; - break; - } - } - } - if (selected) - continue; - - //### NODE TYPES - for (LookupEntry *entry = nodeTypeTable; entry->sval ; entry++) - { - p2 = match(p, entry->sval); - if (p2 > p) - { - lexTokAdd(NODE_TYPE, p, (long)entry->ival); - p = p2; - selected = true; - break; - } - } - if (selected) - continue; - - //### AXIS NAMES - for (LookupEntry *entry = axisNameTable; entry->sval ; entry++) - { - p2 = match(p, entry->sval); - if (p2 > p) - { - lexTokAdd(AXIS_NAME, p, (long)entry->ival); - p = p2; - selected = true; - break; - } - } - if (selected) - continue; - - //### NAME TEST - DOMString ntResult; - p2 = getNameTest(p, ntResult); - if (p2 > p) - { - int p3 = skipwhite(p2); - if (peek(p3) == '(') - lexTokAdd(FUNCTION_NAME, p, ntResult); - else - lexTokAdd(NAME_TEST, p, ntResult); - p = p2; - selected = true; - } - if (selected) - continue; - - //### VARIABLE REFERENCE - if (peek(p) == '$') - { - p++; - DOMString qnResult; - p2 = getNCName(p, qnResult); - if (p2 > p) - { - lexTokAdd(VARIABLE_REFERENCE, p, qnResult); - p = p2; - selected = true; - } - else - { - error("Variable referenced with '$' requires a qualified name\n"); - return -1; - } - } - if (selected) - continue; - - //### NUMBER - double numval; - p2 = getNumber(p, numval); - if (p2 > p) - { - lexTokAdd(NUMBER, p, numval); - p = p2; - selected = true; - } - if (selected) - continue; - - //### LITERAL - DOMString strval; - p2 = getLiteral(p, strval); - if (p2 > p) - { - lexTokAdd(LITERAL, p, strval); - p = p2; - selected = true; - } - if (selected) - continue; - - //### CHAR (default, none of the above) - lexTokAdd(CHAR, p, (long) peek(p)); - p++; - - }//while p - - - return p; -} - - - - - - - - - - - - - - - - - - - - - - -//######################################################################### -//# X P A T H G R A M M A R P A R S I N G -//######################################################################### - -/** - * [1] LocationPath ::= - * RelativeLocationPath - * | AbsoluteLocationPath - */ -int XPathParser::getLocationPath(int p0, int depth) -{ - traceStack("getLocationPath", p0, depth); - int p = p0; - - p = skipwhite(p); - - int p2 = getAbsoluteLocationPath(p, depth+1); - if (p2 > p) - return p2; - - p2 = getRelativeLocationPath(p, depth+1); - if (p2 > p) - return p2; - - return p0; -} - - -/** - * [2] AbsoluteLocationPath ::= - * '/' RelativeLocationPath? - * | AbbreviatedAbsoluteLocationPath - */ -int XPathParser::getAbsoluteLocationPath(int p0, int depth) -{ - traceStack("getAbsoluteLocationPath", p0, depth); - - int p = p0; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue()==SLASH) - { - p++; - int p2 = getRelativeLocationPath(p, depth+1); - if (p2 <= p) - { - error("Relative path after '/'"); - return -1; - } - p = p2; - return p; - } - - //AbbreviatedAbsoluteLocationPath - if (t.getType() == OPERATOR && t.getIntValue()==DOUBLE_SLASH) - { - p++; - int p2 = getRelativeLocationPath(p, depth+1); - if (p2 <= p) - { - error("Relative path after '//'"); - return -1; - } - p = p2; - return p; - } - - - return p0; -} - - -/** - * [3] RelativeLocationPath ::= - * Step - * | RelativeLocationPath '/' Step - * | AbbreviatedRelativeLocationPath - */ -int XPathParser::getRelativeLocationPath(int p0, int depth) -{ - traceStack("getRelativeLocationPath", p0, depth); - int p = p0; - int p2 = getStep(p, depth+1); - if (p2 < 0) - return -1; - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue()==SLASH) - { - p++; - p2 = getRelativeLocationPath(p, depth+1); - if (p2 < 0) - { - error("Relative path after '/'"); - return -1; - } - p = p2; - return p; - } - //AbbreviatedRelativeLocationPath - if (t.getType() == OPERATOR && t.getIntValue()==DOUBLE_SLASH) - { - p++; - p2 = getRelativeLocationPath(p, depth+1); - if (p2 < 0) - { - error("Relative path after '//'"); - return -1; - } - p = p2; - return p; - } - return p; - } - - - return p0; -} - - -/** - * [4] Step ::= - * AxisSpecifier NodeTest Predicate* - * | AbbreviatedStep - */ -int XPathParser::getStep(int p0, int depth) -{ - traceStack("getStep", p0, depth); - - int p = p0; - - lexTok(p).print(); - - //This can be (and usually is) 0-length - int p2 = getAxisSpecifier(p, depth+1); - if (p2 < 0) - { - error("Axis specifier in step section"); - return -1; - } - - p = p2; - p2 = getNodeTest(p, depth+1); - if (p2 < 0) - { - error("Node test in step section"); - return -1; - } - - if (p2 > p) - { - p = p2; - p2 = getPredicate(p, depth+1); - if (p2 < 0) - { - error("Predicate in step section"); - return -1; - } - p = p2; - return p; - } - - //AbbreviatedStep - if (lexTokType(p) == DOT) - { - p++; - return p; - } - - //AbbreviatedStep - if (lexTokType(p) == DOUBLE_DOT) - { - p++; - return p; - } - - return p0; -} - - -/** - * [5] AxisSpecifier ::= - * AxisName '::' - * | AbbreviatedAxisSpecifier - */ -int XPathParser::getAxisSpecifier(int p0, int depth) -{ - traceStack("getAxisSpecifier", p0, depth); - int p = p0; - if (lexTokType(p) == AXIS_NAME) - { - p++; - if (lexTokType(p) != DOUBLE_COLON) - { - error("'::' required after axis name literal"); - return -1; - } - p++; - return p; - } - - //AbbreviatedAxisSpecifier - if (lexTokType(p) == AMPR) - { - p++; - return p; - } - - return p0; -} - - -/** - * [6] AxisName ::= - * 'ancestor' - * | 'ancestor-or-self' - * | 'attribute' - * | 'child' - * | 'descendant' - * | 'descendant-or-self' - * | 'following' - * | 'following-sibling' - * | 'namespace' - * | 'parent' - * | 'preceding' - * | 'preceding-sibling' - * | 'self' - * NOTE: This definition, and those at the bottom, is not - * needed. Its functionality is handled by lexical scanning. - * It is left here for reference. - */ -int XPathParser::getAxisName(int p0, int depth) -{ - traceStack("getAxisName", p0, depth); - return p0; -} - - -/** - * [7] NodeTest ::= - * NameTest - * | NodeType '(' ')' - * | 'processing-instruction' '(' Literal ')' - */ -int XPathParser::getNodeTest(int p0, int depth) -{ - traceStack("getNodeTest", p0, depth); - - int p = p0; - - LexTok t = lexTok(p); - if (t.getType() == NAME_TEST) - { - p++; - return p; - } - - if (t.getType() == NODE_TYPE) - { - if (t.getIntValue() == PROCESSING_INSTRUCTION) - { - if (lexTokType(p) != LPAREN || - lexTokType(p+1) != LITERAL || - lexTokType(p+2) != RPAREN ) - { - error("processing instruction requires (\"literal string\")"); - return -1; - } - p += 3; - } - else - { - if (lexTokType(p+1) != LPAREN || - lexTokType(p+2) != RPAREN ) - { - error("processing instruction requires ()"); - return -1; - } - p += 2; - } - return p; - } - - return p0; -} - - -/** - * [8] Predicate ::= - * '[' PredicateExpr ']' - */ -int XPathParser::getPredicate(int p0, int depth) -{ - traceStack("getPredicate", p0, depth); - - int p = p0; - if (lexTokType(p) != LBRACKET) - return p0; - - p++; - int p2 = getPredicateExpr(p, depth+1); - if (p2 <= p) - { - error("Predicate expression in predicate"); - return -1; - } - - p = p2; - lexTok(p).print(); - if (lexTokType(p) != RBRACKET) - { - error("Predicate expression requires closing ']'"); - return -1; - } - p++; - return p; -} - - -/** - * [9] PredicateExpr ::= - * Expr - */ -int XPathParser::getPredicateExpr(int p0, int depth) -{ - traceStack("getPredicateExpr", p0, depth); - int p = p0; - int p2 = getExpr(p, depth+1); - if (p2 < 0) - { - error("Expression in predicate expression"); - return -1; - } - p = p2; - return p; -} - - -/** - * [10] AbbreviatedAbsoluteLocationPath ::= - * '//' RelativeLocationPath - * NOTE: not used. handled in getAbsoluteLocationPath() - */ -int XPathParser::getAbbreviatedAbsoluteLocationPath(int p0, int depth) -{ - traceStack("getAbbreviatedAbsoluteLocationPath", p0, depth); - - return p0; -} - -/** - * [11] AbbreviatedRelativeLocationPath ::= - * RelativeLocationPath '//' Step - * NOTE: not used. handled in getRelativeLocationPath() - */ -int XPathParser::getAbbreviatedRelativeLocationPath(int p0, int depth) -{ - traceStack("getAbbreviatedRelativeLocationPath", p0, depth); - return p0; -} - -/** - * [12] AbbreviatedStep ::= - * '.' - * | '..' - * NOTE: not used. handled in getStep() - */ -int XPathParser::getAbbreviatedStep(int p0, int depth) -{ - traceStack("getAbbreviatedStep", p0, depth); - return p0; -} - - -/** - * [13] AbbreviatedAxisSpecifier ::= - * '@'? - * NOTE: not used. handled in getAxisSpecifier() - */ -int XPathParser::getAbbreviatedAxisSpecifier(int p0, int depth) -{ - traceStack("getAbbreviatedAxisSpecifier", p0, depth); - return p0; -} - - -/** - * [14] Expr ::= - * OrExpr - */ -int XPathParser::getExpr(int p0, int depth) -{ - traceStack("getExpr", p0, depth); - - int p = p0; - - int p2 = getOrExpr(p, depth+1); - if (p2 < 0) - { - error("OR expression in expression"); - return -1; - } - p = p2; - - return p; -} - - -/** - * [15] PrimaryExpr ::= - * VariableReference - * | '(' Expr ')' - * | Literal - * | Number - * | FunctionCall - */ -int XPathParser::getPrimaryExpr(int p0, int depth) -{ - traceStack("getPrimaryExpr", p0, depth); - int p = p0; - int p2 = p; - - if (lexTokType(p) == VARIABLE_REFERENCE) - { - p++; - return p; - } - - if (lexTokType(p) == LPAREN) - { - p++; - p2 = getExpr(p, depth+1); - if (p2 <= p) - { - error("Expression in primary expression"); - return -1; - } - p += p2; - if (lexTokType(p) != RPAREN) - { - error("Primary expression requires closing ')'"); - return -1; - } - } - - if (lexTokType(p) == LITERAL) - { - p++; - return p; - } - - if (lexTokType(p) == NUMBER) - { - p++; - return p; - } - - p2 = getFunctionCall(p, depth+1); - if (p2 < 0) - { - error("Function call in primary expression"); - return -1; - } - if (p2 > p) - { - p = p2; - return p; - } - - return p0; -} - - -/** - * [16] FunctionCall ::= - * FunctionName '(' ( Argument ( ',' Argument )* )? ')' - */ -int XPathParser::getFunctionCall(int p0, int depth) -{ - traceStack("getFunctionCall", p0, depth); - int p = p0; - - if (lexTokType(p) != FUNCTION_NAME) - return p0; - - p++; - - if (lexTokType(p) != LPAREN) //this makes a function - return p0; - p++; - - int p2 = getArgument(p, depth+1); - if (p2 < 0) - { - error("Error in function argument"); - return -1; - } - if (p2 > p) - { - p = p2; - while (lexTokType(p) == COMMA) - { - p++; - p2 = getArgument(p, depth+1); - if (p2 <= p) - { - error("Error in function argument"); - return -1; - } - p = p2; - } - } - - if (lexTokType(p) != RPAREN) //mandatory - { - error("Function requires closing ')'"); - return -1; - } - p++; - - return p; -} - - -/** - * [17] Argument ::= - * Expr - */ -int XPathParser::getArgument(int p0, int depth) -{ - traceStack("getArgument", p0, depth); - int p = p0; - int p2 = getExpr(p, depth+1); - if (p2 < 0) - { - error("Argument expression"); - return -1; - } - p = p2; - return p; -} - - -/** - * [18] UnionExpr ::= - * PathExpr - * | UnionExpr '|' PathExpr - */ -int XPathParser::getUnionExpr(int p0, int depth) -{ - traceStack("getUnionExpr", p0, depth); - int p = p0; - int p2 = getPathExpr(p, depth+1); - if (p2 < 0) - { - error("Path expression for union"); - return -1; - } - p = p2; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue() == PIPE) - { - p++; - p2 = getUnionExpr(p, depth+1); - if (p2 < 0) - { - error("OR (|) requires union expression on the left"); - return -1; - } - p = p2; - } - return p; -} - - -/** - * [19] PathExpr ::= - * LocationPath - * | FilterExpr - * | FilterExpr '/' RelativeLocationPath - * | FilterExpr '//' RelativeLocationPath - */ -int XPathParser::getPathExpr(int p0, int depth) -{ - traceStack("getPathExpr", p0, depth); - int p = p0; - int p2; - - p2 = getLocationPath(p, depth+1); - if (p2 < 0) - { - error("Location path in path expression"); - return -1; - } - if (p2 > p) - { - p = p2; - return p; - } - - p2 = getFilterExpr(p, depth+1); - if (p2 < 0) - { - error("Filter expression in path expression"); - return -1; - } - if (p2 <= p) - return p0; - p = p2; - - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue() == SLASH) - { - p++; - p2 = getRelativeLocationPath(p, depth+1); - if (p2 < 0) - { - error("Relative location after / in path expression"); - return -1; - } - p = p2; - return p; - } - - if (t.getType() == OPERATOR && t.getIntValue() == DOUBLE_SLASH) - { - p++; - p2 = getRelativeLocationPath(p, depth+1); - if (p2 < 0) - { - error("Relative location after // in path expression"); - return -1; - } - p = p2; - return p; - } - return p; -} - - -/** - * [20] FilterExpr ::= - * PrimaryExpr - * | FilterExpr Predicate - */ -int XPathParser::getFilterExpr(int p0, int depth) -{ - traceStack("getFilterExpr", p0, depth); - int p = p0; - - int p2 = getPrimaryExpr(p, depth+1); - if (p2 < 0) - { - error("Primary expression in path expression"); - return -1; - } - if (p2 > p) - { - p = p2; - while (true) - { - p2 = getPredicate(p, depth+1); - if (p2 < 0) - { - error("Predicate in primary expression"); - return -1; - } - if (p2 > p) - { - p = p2; - } - else - break; - } - return p; - } - - return p0; -} - - -/** - * [21] OrExpr ::= - * AndExpr - * | OrExpr 'or' AndExpr - */ -int XPathParser::getOrExpr(int p0, int depth) -{ - traceStack("getOrExpr", p0, depth); - int p = p0; - int p2 = getAndExpr(p, depth+1); - if (p2 < 0) - { - error("AND expression in OR expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue() == OR) - { - p++; - p2 = getAndExpr(p, depth+1); - if (p2 <= p) - { - error("AND expression in OR expression"); - return -1; - } - p = p2; - return p; - } - return p; - } - - return p0; -} - - -/** - * [22] AndExpr ::= - * EqualityExpr - * | AndExpr 'and' EqualityExpr - */ -int XPathParser::getAndExpr(int p0, int depth) -{ - traceStack("getAndExpr", p0, depth); - int p = p0; - int p2 = getEqualityExpr(p, depth+1); - if (p2 < 0) - { - error("Equality expression in AND expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue() == AND) - { - p++; - p2 = getAndExpr(p, depth+1); - if (p2 <= p) - { - error("AND expression after 'and'"); - return -1; - } - p = p2; - return p; - } - return p; - } - - return p0; -} - - -/** - * [23] EqualityExpr ::= - * RelationalExpr - * | EqualityExpr '=' RelationalExpr - * | EqualityExpr '!=' RelationalExpr - */ -int XPathParser::getEqualityExpr(int p0, int depth) -{ - traceStack("getEqualityExpr", p0, depth); - int p = p0; - int p2 = getRelationalExpr(p, depth+1); - if (p2 < 0) - { - error("Relation expression in equality expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - if (t.getType() == OPERATOR && t.getIntValue() == EQUALS) - { - p++; - p2 = getEqualityExpr(p, depth+1); - if (p2 <= p) - { - error("Equality expression expected after =="); - return -1; - } - p = p2; - return p; - } - - if (t.getType() == OPERATOR && t.getIntValue() == NOT_EQUALS) - { - p++; - p2 = getEqualityExpr(p, depth+1); - if (p2 <= p) - { - error("Equality expression expected after !="); - return -1; - } - p = p2; - return p; - } - - return p; - } - - return p0; -} - - -/** - * [24] RelationalExpr ::= - * AdditiveExpr - * | RelationalExpr '<' AdditiveExpr - * | RelationalExpr '>' AdditiveExpr - * | RelationalExpr '<=' AdditiveExpr - * | RelationalExpr '>=' AdditiveExpr - */ -int XPathParser::getRelationalExpr(int p0, int depth) -{ - traceStack("getRelationalExpr", p0, depth); - int p = p0; - int p2 = getAdditiveExpr(p, depth+1); - if (p2 < 0) - { - error("Additive expression in relational expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - - if (t.getType() == OPERATOR && t.getIntValue() == GREATER_THAN) - { - p++; - p2 = getRelationalExpr(p, depth+1); - if (p2 <= p) - { - error("Relational expression after '>'"); - return -1; - } - p = p2; - return p; - } - if (t.getType() == OPERATOR && t.getIntValue() == LESS_THAN) - { - p++; - p2 = getRelationalExpr(p, depth+1); - if (p2 <= p) - { - error("Relational expression after '<'"); - return -1; - } - p = p2; - return p; - } - if (t.getType() == OPERATOR && t.getIntValue() == GREATER_THAN_EQUALS) - { - p++; - p2 = getRelationalExpr(p, depth+1); - if (p2 <= p) - { - error("Relational expression after '>='"); - return -1; - } - p = p2; - return p; - } - if (t.getType() == OPERATOR && t.getIntValue() == LESS_THAN_EQUALS) - { - p++; - p2 = getRelationalExpr(p, depth+1); - if (p2 <= p) - { - error("Relational expression after '<='"); - return -1; - } - p = p2; - return p; - } - - - return p; - } - - return p0; -} - - -/** - * [25] AdditiveExp ::= - * MultiplicativeExpr - * | AdditiveExpr '+' MultiplicativeExpr - * | AdditiveExpr '-' MultiplicativeExpr - */ -int XPathParser::getAdditiveExpr(int p0, int depth) -{ - traceStack("getAdditiveExpr", p0, depth); - int p = p0; - int p2 = getMultiplicativeExpr(p, depth+1); - if (p2 < 0) - { - error("Multiplicative expression in additive expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - - if (t.getType() == OPERATOR && t.getIntValue() == PLUS) - { - p++; - p2 = getAdditiveExpr(p, depth+1); - if (p2 <= p) - { - error("Additive expression after '+'"); - return -1; - } - p = p2; - return p; - } - if (t.getType() == OPERATOR && t.getIntValue() == MINUS) - { - p++; - p2 = getAdditiveExpr(p, depth+1); - if (p2 <= p) - { - error("Additive expression after '-'"); - return -1; - } - p = p2; - return p; - } - - - return p; - } - - return p0; -} - - -/** - * [26] MultiplicativeExpr ::= - * UnaryExpr - * | MultiplicativeExpr MultiplyOperator UnaryExpr - * | MultiplicativeExpr 'div' UnaryExpr - * | MultiplicativeExpr 'mod' UnaryExpr - */ -int XPathParser::getMultiplicativeExpr(int p0, int depth) -{ - traceStack("getMultiplicativeExpr", p0, depth); - int p = p0; - int p2 = getUnaryExpr(p, depth+1); - if (p2 < 0) - { - error("Unary expression in multiplicative expression"); - return -1; - } - if (p2 > p) - { - p = p2; - LexTok t = lexTok(p); - - if (t.getType() == OPERATOR && t.getIntValue() == MULTIPLY) - { - p++; - p2 = getMultiplicativeExpr(p, depth+1); - if (p2 <= p) - { - error("Multiplicative expression after '*'"); - return -1; - } - p = p2; - return p; - } - - if (t.getType() == OPERATOR && t.getIntValue() == DIV) - { - p++; - p2 = getMultiplicativeExpr(p, depth+1); - if (p2 <= p) - { - error("Multiplicative expression after 'div'"); - return -1; - } - p = p2; - return p; - } - - if (t.getType() == OPERATOR && t.getIntValue() == MOD) - { - p++; - p2 = getMultiplicativeExpr(p, depth+1); - if (p2 <= p) - { - error("Multiplicative expression after 'mod'"); - return -1; - } - p = p2; - return p; - } - - - return p; - } - - return p0; -} - - -/** - * [27] UnaryExpr ::= - * UnionExpr - * | '-' UnaryExpr - */ -int XPathParser::getUnaryExpr(int p0, int depth) -{ - traceStack("getUnaryExpr", p0, depth); - int p = p0; - int p2 = getUnionExpr(p, depth+1); - if (p2 < 0) - { - error("Union expression in unary expression"); - return -1; - } - if (p2 > p) - { - p = p2; - return p; - } - - if (lexTokType(p) == '-') - { - p++; - p2 = getUnaryExpr(p, depth+1); - if (p2 < 0) - { - error("Unary expression after '-'"); - return -1; - } - p = p2; - return p; - } - - return p0; -} - - -//###################################################### -//# NOT USED!!! -//## The grammar definitions below are -//## handled by lexical parsing, and will not be used -//###################################################### - -/** - * [28] ExprToken ::= - * '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' - * | NameTest - * | NodeType - * | Operator - * | FunctionName - * | AxisName - * | Literal - * | Number - * | VariableReference - */ -int XPathParser::getExprToken(int p0, int depth) -{ - traceStack("getExprToken", p0, depth); - return p0; -} - - -/** - * [29] Literal ::= - * '"' [^"]* '"' - * | "'" [^']* "'" - */ -int XPathParser::getLiteral(int p0, int depth) -{ - traceStack("getLiteral", p0, depth); - return p0; -} - - -/** - * [30] Number ::= - * Digits ('.' Digits?)? - * | '.' Digits - */ -int XPathParser::getNumber(int p0, int depth) -{ - traceStack("getNumber", p0, depth); - return p0; -} - - -/** - * [31] Digits ::= - * [0-9]+ - */ -int XPathParser::getDigits(int p0, int depth) -{ - traceStack("getDigits", p0, depth); - return p0; -} - - -/** - * [32] Operator ::= - * OperatorName - * | MultiplyOperator - * | '/' | '//' | '|' | '+' | '-' | '=' - * | '!=' | '<' | '<=' | '>' | '>=' - */ -int XPathParser::getOperator(int p0, int depth) -{ - traceStack("getOperator", p0, depth); - return p0; -} - - -/** - * [33] OperatorName ::= - * 'and' | 'or' | 'mod' | 'div' - */ -int XPathParser::getOperatorName(int p0, int depth) -{ - traceStack("getOperatorName", p0, depth); - return p0; -} - - -/** - * [34] MultiplyOperator ::= - * '*' - */ -int XPathParser::getMultiplyOperator(int p0, int depth) -{ - traceStack("getMultiplyOperator", p0, depth); - return p0; -} - - -/** - * [35] FunctionName ::= - * QName - NodeType - */ -int XPathParser::getFunctionName(int p0, int depth) -{ - traceStack("getFunctionName", p0, depth); - return p0; -} - - -/** - * [36] VariableReference ::= - * '$' QName - */ -int XPathParser::getVariableReference(int p0, int depth) -{ - traceStack("getVariableReference", p0, depth); - return p0; -} - - -/** - * [37] NameTest ::= - * '*' - * | NCName ':' '*' - * | QName - */ -int XPathParser::getNameTest(int p0, int depth) -{ - traceStack("getNameTest", p0, depth); - return p0; -} - - -/** - * [38] NodeType ::= - * 'comment' - * | 'text' - * | 'processing-instruction' - * | 'node' - */ -int XPathParser::getNodeType(int p0, int depth) -{ - traceStack("getNodeType", p0, depth); - return p0; -} - - -/** - * [39] ExprWhitespace ::= - * S - */ -int XPathParser::getExprWhitespace(int p0, int depth) -{ - traceStack("getExprWhitespace", p0, depth); - return p0; -} - - - - - -//######################################################################### -//# H I G H L E V E L P A R S I N G -//######################################################################### - -/** - * Parse a candidate XPath string. Leave a copy in 'tokens.' - */ -bool XPathParser::parse(const DOMString &xpathString) -{ - int p0 = 0; - - DOMString str = xpathString; - - parsebuf = (char *)str.c_str(); - parselen = (int) str.size(); - position = 0; - - trace("## parsing string: '%s'", parsebuf); - - lexicalScan(); - lexicalTokenDump(); - - tokens.clear();//Get ready to store new tokens - - int p = getLocationPath(p0, 0); - - parsebuf = NULL; - parselen = 0; - - if (p <= p0) - { - //return false; - } - - return true; -} - - - - - -//######################################################################### -//# E V A L U A T E -//######################################################################### - -/** - * This method "executes" a list of Tokens in the context of a DOM root - * Node, returning a list of Nodes that match the xpath expression. - */ -NodeList XPathParser::execute(const Node *root, - std::vector &toks) -{ - NodeList list; - - if (!root) - return list; - - //### Execute the token list - std::vector::iterator iter; - for (iter = toks.begin() ; iter != toks.end() ; iter++) - { - } - - return list; -} - - - - -/** - * This wraps the two-step call to parse(), then execute() to get a NodeList - * of matching DOM nodes - */ -NodeList XPathParser::evaluate(const Node *root, const DOMString &xpathString) -{ - NodeList list; - - //### Maybe do caching for speed here - - //### Parse and execute - //### Error message can be generated as a side effect - if (!parse(xpathString)) - return list; - - //### Execute the token list - list = execute(root, tokens); - - return list; -} - - - -} // namespace xpath -} // namespace dom -} // namespace w3c -} // namespace org -//######################################################################### -//# E N D O F F I L E -//######################################################################### - - - - -- cgit v1.2.3