xpathparser.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,355 行 · 第 1/3 页

JAVA
1,355
字号
    int ch = skipWhitespace(read());    AbstractPattern tagPattern;    if (ch == '(') {      Expr expr = parseFunction(pattern, pattern, name, fromChildren);      return expr.toNodeList();    }    else if (ch == '{') {      tag.clear();      while ((ch = read()) >= 0 && ch != '}')        tag.append((char) ch);      String url = tag.toString();      tag.clear();      for (ch = read(); XmlChar.isNameChar(ch); ch = read())        tag.append((char) ch);      pattern = new NSNamePattern(pattern, url, tag.toString(), nodeType);    }    else {      if (fromChildren)	pattern = new FromChildren(pattern);      if (name.equals("*"))	pattern = NodeTypePattern.create(pattern, nodeType);      else if (name.endsWith(":*")) {	pattern = new NamespacePattern(pattern,				       name.substring(0, name.length() - 2),				       nodeType);      }      else {	int p = name.indexOf(':');	String ns = null;	String local = name;	if (p > 0) {	  String prefix = name.substring(0, p);	  ns = NamespaceContext.find(_namespace, prefix);	  local = name.substring(p + 1);	}	else if (nodeType != Node.ATTRIBUTE_NODE)	  ns = _namespace.find(_namespace, "");	else	  ns = null; // _namespace.find(_namespace, "");	if (ns == null)	  pattern = new NodePattern(pattern, name, nodeType);	else	  pattern = new NSNamePattern(pattern, ns, local, nodeType);      }    }    unread();    return pattern;  }  /**   * expr ::= or-expr   */  Expr parseExpr(AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    peek = -1;    Expr left = parseTerm(parent, listParent);    while (true) {      int token = scanToken();      switch (token) {      case Expr.OR:	left = parseOrExpr(token, left, parseTerm(parent, listParent),			   parent, listParent);	break;      case Expr.AND:	left = parseAndExpr(token, left, parseTerm(parent, listParent),			    parent, listParent);	break;      case Expr.EQ: case Expr.NEQ: case Expr.LT:      case Expr.LE: case Expr.GT: case Expr.GE:	left = parseCmpExpr(token, left, parseTerm(parent, listParent),			    parent, listParent);	break;      case Expr.ADD: case Expr.SUB:	left = parseAddExpr(token, left, parseTerm(parent, listParent),			    parent, listParent);	break;      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	left = parseMulExpr(token, left, parseTerm(parent, listParent),			    parent, listParent);	break;      default:	return left;      }    }  }  /**   * or-expr ::= or-expr 'OR' expr   *           | and-expr   */  private Expr parseOrExpr(int code, Expr left, Expr right,			   AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.OR:	left = new BooleanExpr(code, left, right);	code = token;	right = parseTerm(parent, listParent);	break;      case Expr.AND:	right = parseAndExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.EQ: case Expr.NEQ: case Expr.LT:      case Expr.LE: case Expr.GT: case Expr.GE:	right = parseCmpExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      default:	undoToken(token);	return new BooleanExpr(code, left, right);      }    }  }  /**   * and-expr ::= and-expr 'AND' expr   *            | cmp-expr   */  private Expr parseAndExpr(int code, Expr left, Expr right,			    AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.AND:	left = new BooleanExpr(code, left, right);	code = token;	right = parseTerm(parent, listParent);	break;      case Expr.EQ: case Expr.NEQ: case Expr.LT:      case Expr.LE: case Expr.GT: case Expr.GE:	right = parseCmpExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      default:	undoToken(token);	return new BooleanExpr(code, left, right);      }    }  }  /**   * cmp-expr ::= cmp-expr '<' expr   *            | add-expr   */  private Expr parseCmpExpr(int code, Expr left, Expr right,			    AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.EQ: case Expr.NEQ: case Expr.LT:      case Expr.LE: case Expr.GT: case Expr.GE:	left = new BooleanExpr(code, left, right);	code = token;	right = parseTerm(parent, listParent);	break;      case Expr.ADD: case Expr.SUB:	right = parseAddExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      default:	undoToken(token);	return new BooleanExpr(code, left, right);      }    }  }  /**   * add-expr ::= add-expr '+' expr   *            | mul-expr   */  private Expr parseAddExpr(int code, Expr left, Expr right,			    AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.ADD: case Expr.SUB:	left = new NumericExpr(code, left, right);	code = token;	right = parseTerm(parent, listParent);	break;      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	right = parseMulExpr(token, right, parseTerm(parent, listParent),			     parent, listParent);	break;      default:	undoToken(token);	return new NumericExpr(code, left, right);      }    }  }  /**   * mul-expr ::= mul-expr '*' expr   *            | term   */  private Expr parseMulExpr(int code, Expr left, Expr right,			    AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    while (true) {      int token = scanToken();      switch (token) {      case Expr.MUL: case Expr.DIV: case Expr.QUO: case Expr.MOD:	left = new NumericExpr(code, left, right);	code = token;	right = parseTerm(parent, listParent);	break;      default:	undoToken(token);	return new NumericExpr(code, left, right);      }    }  }  /**   * term ::= simple-term path?   */  private Expr parseTerm(AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    int ch = skipWhitespace(read());    unread();    Expr expr = parseSimpleTerm(parent, listParent);    int nextCh = skipWhitespace(read());    unread();    if (nextCh == '/' || nextCh == '[') {      AbstractPattern pattern = expr.toNodeList();      if (ch == '(' && ! pattern.isStrictlyAscending())        pattern = new FromExpr(null, expr);	      return NodeSetExpr.create(parseUnion(parsePath(parseFilter(pattern)),                                           pattern));    }    else if (nextCh == '|') {      AbstractPattern pattern = expr.toNodeList();      return NodeSetExpr.create(parseUnion(parsePath(parseFilter(pattern)),                                           listParent));    }    else      return expr;  }  /**   * simple-term ::= number   *             ::= '(' expr ')'   *             ::= '$' variable   *             ::= '"' string '"'   *             ::= node-set   */  private Expr parseSimpleTerm(AbstractPattern parent, AbstractPattern listParent)    throws XPathParseException  {    int ch = read();        ch = skipWhitespace(ch);    switch (ch) {    case '.':      ch = read();      unread();      unread();      if (! ('0' <= ch && ch <= '9')) {	return NodeSetExpr.create(parseUnion(parseBasisTop(parent), parent));      }      ch = read();      // fall through to parse the number    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':      {	long value = 0;	double exp = 1;        int digits = 0;	for (; ch >= '0' && ch <= '9'; ch = read())	  value = 10 * value + ch - '0';	if (ch == '.') {	  for (ch = read(); ch >= '0' && ch <= '9'; ch = read()) {	    value = 10 * value + ch - '0';	    exp *= 10;            digits--;	  }	}        if (ch == 'e' || ch == 'E') {          int sign = 1;          int expValue = 0;                    ch = read();          if (ch == '-') {            sign = -1;            ch = read();          }          else if (ch == '+')            ch = read();                    for (; ch >= '0' && ch <= '9'; ch = read())            expValue = 10 * expValue + ch - '0';          exp = Math.pow(10, digits + sign * expValue);          unread();                    return new NumericExpr((double) value * (double) exp);        }        	unread();	return new NumericExpr((double) value / (double) exp);      }    case '-':      return new NumericExpr(Expr.NEG, parseTerm(parent, listParent));    case '+':      return parseTerm(parent, listParent);    case '(':      {	Expr expr = parseExpr(parent, listParent);	if ((ch = skipWhitespace(read())) != ')')	  throw error(L.l("expected `{0}' at {1}", ")", badChar(ch)));		return expr;      }    case '/': case '@': case '*':      unread();      return NodeSetExpr.create(parseUnion(parseBasisTop(parent), parent));    case '\'': case '"':      {	int end = ch;	CharBuffer cb = new CharBuffer();        for (ch = read(); ch >= 0; ch = read()) {          if (ch != end)            cb.append((char) ch);          else if ((ch = read()) == end)            cb.append((char) ch);          else {            unread();            break;          }        }	return new StringExpr(cb.toString());      }    case '$':      {	String name = readName(read());	return new VarExpr(name);      }    default:      if (! XmlChar.isNameStart(ch))	throw error(L.l("unknown character at {0}", badChar(ch)));      String name = readName(ch);      ch = skipWhitespace(read());      int axisIndex = name.indexOf("::");      // make sure axis are treated as node sets      if (ch == '(' && axisIndex < 0) {	return parseFunction(parent, listParent, name, true);      }      else if (ch == '(') {	String axis = name.substring(0, axisIndex);	if (axisMap.get(axis) <= 0)	  return parseFunction(parent, listParent, name, true);      }            unread();      if (parent == null)	parent = new FromContext();      return parseNodeSetExpr(parent, name, Node.ELEMENT_NODE);    }  }  /**   * function ::= name '(' args ')'   *   * The XPath library functions are hard-coded for a little extra   * execution efficiency.   */  Expr parseFunction(AbstractPattern parent,                     AbstractPattern listParent,                     String name,		     boolean fromChildren)    throws XPathParseException

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?