📄 xqparser.java
字号:
func = makeFunctionExp("gnu.xquery.util.Compare", ">"); break; case OP_GEQ: func = makeFunctionExp("gnu.xquery.util.Compare", ">="); break; case OP_IS: func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Eq", "is"); break; case OP_ISNOT: func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Ne", "isnot"); break; case OP_GRTGRT: func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Gr", ">>"); break; case OP_LSSLSS: func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Ls", "<<"); break; case OP_RANGE_TO: func = makeFunctionExp("gnu.xquery.util.IntegerRange", "integerRange"); break; case OP_UNION: func = makeFunctionExp("gnu.kawa.xml.UnionNodes", "unionNodes"); break; case OP_INTERSECT: func = makeFunctionExp("gnu.kawa.xml.IntersectNodes", "intersectNodes"); break; case OP_EXCEPT: func = makeFunctionExp("gnu.kawa.xml.IntersectNodes", "exceptNodes"); break; default: return syntaxError("unimplemented binary op: "+op); } return makeBinary(func, exp1, exp2); } private void parseSimpleKindType () throws java.io.IOException, SyntaxException { getRawToken(); if (curToken == ')') getRawToken(); else error("expected ')'"); } public Expression parseNamedNodeType (boolean attribute) throws java.io.IOException, SyntaxException { Expression qname; getRawToken(); if (curToken == ')') { qname = QuoteExp.getInstance(ElementType.MATCH_ANY_QNAME); getRawToken(); } else { if (curToken == QNAME_TOKEN || curToken == NCNAME_TOKEN) qname = parseNameTest(attribute); else { if (curToken != OP_MUL) syntaxError("expected QName or *"); qname = QuoteExp.getInstance(ElementType.MATCH_ANY_QNAME); } getRawToken(); if (curToken == ',') { getRawToken(); if (curToken == QNAME_TOKEN || curToken == NCNAME_TOKEN) { Expression tname = parseNameTest(true); } else syntaxError("expected QName"); getRawToken(); } if (curToken == ')') getRawToken(); else error("expected ')' after element"); } return makeNamedNodeType(attribute, qname); } static Expression makeNamedNodeType (boolean attribute, Expression qname) { Expression[] name = new Expression[2]; ClassType nodeType = ClassType.make(attribute ? "gnu.kawa.xml.AttributeType" : "gnu.kawa.xml.ElementType"); ApplyExp elt = new ApplyExp(nodeType.getDeclaredMethod("make", 1), new Expression[] { qname }); elt.setFlag(ApplyExp.INLINE_IF_CONSTANT); return elt; } private boolean warnedOldStyleKindTest; private void warnOldStyleKindTest() { if (warnedOldStyleKindTest) return; error('w', "old-style KindTest - first one here"); warnedOldStyleKindTest = true; } /** Parse: ["as" SequenceType] */ public Expression parseOptionalTypeDeclaration () throws java.io.IOException, SyntaxException { if (! match("as")) return null; getRawToken(); return parseDataType(); } public Expression parseDataType() throws java.io.IOException, SyntaxException { Expression etype = parseItemType(); int min, max; if (etype == null) { if (curToken != OP_EMPTY_SEQUENCE) return syntaxError("bad syntax - expected DataType"); parseSimpleKindType(); if (curToken == '?' || curToken == OP_ADD || curToken == OP_MUL) { getRawToken(); return syntaxError("occurrence-indicator meaningless after empty-sequence()"); } etype = QuoteExp.getInstance(OccurrenceType.emptySequenceType); min = 0; max = 0; } else if (curToken == '?') { min = 0; max = 1; } else if (curToken == OP_ADD) { min = 1; max = -1; } else if (curToken == OP_MUL) { min = 0; max = -1; } else { min = 1; max = 1; } if (parseContext == 'C') { if (max != 1) return syntaxError("type to 'cast as' or 'castable as' must be a 'SingleType'"); } if (min != max) { getRawToken(); Expression[] args = { etype, QuoteExp.getInstance(gnu.math.IntNum.make(min)), QuoteExp.getInstance(gnu.math.IntNum.make(max)) }; ApplyExp otype = new ApplyExp(ClassType.make("gnu.kawa.reflect.OccurrenceType") .getDeclaredMethod("getInstance", 3), args); otype.setFlag(ApplyExp.INLINE_IF_CONSTANT); return otype; } return etype; } public Expression parseMaybeKindTest () throws java.io.IOException, SyntaxException { Type type; switch (curToken) { case OP_ATTRIBUTE: case OP_ELEMENT: return parseNamedNodeType(curToken == OP_ATTRIBUTE); case OP_TEXT: parseSimpleKindType(); type = NodeType.textNodeTest; break; case OP_COMMENT: parseSimpleKindType(); type = NodeType.commentNodeTest; break; case OP_DOCUMENT: parseSimpleKindType(); type = NodeType.documentNodeTest; break; case OP_NODE: parseSimpleKindType(); type = NodeType.anyNodeTest; break; case OP_PI: getRawToken(); String piTarget = null; if (curToken == NCNAME_TOKEN || curToken == STRING_TOKEN) { piTarget = new String(tokenBuffer, 0, tokenBufferLength); getRawToken(); } if (curToken == ')') getRawToken(); else error("expected ')'"); type = ProcessingInstructionType.getInstance(piTarget); break; default: return null; } return QuoteExp.getInstance(type); } public Expression parseItemType() throws java.io.IOException, SyntaxException { peekOperand(); Expression etype = parseMaybeKindTest(); Type type; if (etype != null) { if (parseContext == 'C') // Kludge to force error below. type = XDataType.anyAtomicType; else return etype; } else if (curToken == OP_ITEM) { parseSimpleKindType(); type = SingletonType.getInstance(); } else if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN) { String tname = new String(tokenBuffer, 0, tokenBufferLength); getRawToken(); type = interpreter.getTypeFor(tname); if (type == null) { error('e', "unknown type "+tname, "XPST0051"); type = Type.pointer_type; } } else return null; if (parseContext == 'C') { if (type == SingletonType.getInstance()) return syntaxError("type to 'cast as' or 'castable as' must be atomic", "XPST0080"); if (type == XDataType.anyAtomicType) return syntaxError("type to 'cast as' or 'castable as' cannot be anyAtomicType", "XPST0080"); if (type == XDataType.NotationType) return syntaxError("type to 'cast as' or 'castable as' cannot be NOTATION", "XPST0080"); } return QuoteExp.getInstance(type); } /** Parse a <code>URILiteral</code>.. * @return either a String (on success), * or an ErrorExp (after emitting an error). */ Object parseURILiteral () throws java.io.IOException, SyntaxException { getRawToken(); if (curToken != STRING_TOKEN) return declError("expected a URILiteral"); String str = new String(tokenBuffer, 0, tokenBufferLength); str = TextUtils.replaceWhitespace(str, true); // FUTURE: An implementation MAY raise a static error if the value // of a URILiteral is of nonzero length and is not in the lexical // space of xs:anyURI, or if it is a string that represents a // relative URI as defined in [RFC2396]. err:XQST0046 return str; } Expression parseExpr() throws java.io.IOException, SyntaxException { return parseExprSingle(); } final Expression parseExprSingle () throws java.io.IOException, SyntaxException { int startLine = curLine; int startColumn = curColumn; peekOperand(); switch (curToken) { // FIXME old code tweaked line/column // as in: // maybeSetLine(exp, startLine, startColumn - 3); case IF_LPAREN_TOKEN: return parseIfExpr(); case TYPESWITCH_LPAREN_TOKEN: return parseTypeSwitch(); case FOR_DOLLAR_TOKEN: return parseFLWRExpression(true); case LET_DOLLAR_TOKEN: return parseFLWRExpression(false); case SOME_DOLLAR_TOKEN: return parseQuantifiedExpr(false); case EVERY_DOLLAR_TOKEN: return parseQuantifiedExpr(true); default: return parseBinaryExpr(priority(OP_OR)); } } Expression parseBinaryExpr(int prio) throws java.io.IOException, SyntaxException { Expression exp = parseUnaryExpr(); for (;;) { int token = peekOperator(); if (token == EOL_TOKEN // Following makes for better error handling. || (token == OP_LSS && peek() == '/')) return exp; int tokPriority = priority(token); if (tokPriority < prio) return exp; char saveReadState = pushNesting('%'); getRawToken(); popNesting(saveReadState); if (token >= OP_INSTANCEOF && token <= OP_CAST_AS) { if (token == OP_CAST_AS || token == OP_CASTABLE_AS) parseContext = 'C'; Expression type = parseDataType(); parseContext = '\0'; Expression[] args = new Expression[2]; Expression func; switch (token) { case OP_INSTANCEOF: args[0] = exp; args[1] = type; func = makeFunctionExp("gnu.xquery.lang.XQParser", "instanceOf"); break; case OP_CASTABLE_AS: args[0] = exp; args[1] = type; func = new ReferenceExp(XQResolveNames.castableAsDecl); break; case OP_TREAT_AS: args[0] = type; args[1] = exp; func = makeFunctionExp("gnu.xquery.lang.XQParser", "treatAs"); break; default: // i.e. case OP_CAST_AS: args[0] = type; args[1] = exp; func = new ReferenceExp(XQResolveNames.castAsDecl); break; } exp = new ApplyExp(func, args); } else if (token == OP_INSTANCEOF) { Expression[] args = { exp, parseDataType() }; exp = new ApplyExp(makeFunctionExp("gnu.xquery.lang.XQParser", "instanceOf"), args); } else { Expression exp2 = parseBinaryExpr(tokPriority+1); if (token == OP_AND) exp = new IfExp(booleanValue(exp), booleanValue(exp2), XQuery.falseExp); else if (token == OP_OR) exp = new IfExp(booleanValue(exp), XQuery.trueExp, booleanValue(exp2)); else exp = makeBinary(token, exp, exp2); } } } Expression parseUnaryExpr() throws java.io.IOException, SyntaxException { Expression exp; if (curToken == OP_SUB || curToken == OP_ADD) { int op = curToken; getRawToken(); exp = parseUnaryExpr(); Expression func = makeFunctionExp("gnu.xquery.util.ArithOp", op == OP_ADD ? "plus" : "minus", op == OP_ADD ? "+" : "-"); exp = new ApplyExp(func, new Expression[] { exp }); } else exp = parseUnionExpr(); return exp; } Expression parseUnionExpr() throws java.io.IOException, SyntaxException { Expression exp = parseIntersectExceptExpr(); for (;;) { int op = peekOperator(); if (op != OP_UNION) break; getRawToken(); Expression exp2 = parseIntersectExceptExpr(); exp = makeBinary(op, exp, exp2); } return exp; } Expression parseIntersectExceptExpr() throws java.io.IOException, SyntaxException { Expression exp = parsePathExpr(); for (;;) { int op = peekOperator(); if (op != OP_INTERSECT && op != OP_EXCEPT) break; getRawToken(); Expression exp2 = parsePathExpr(); exp = makeBinary(op, exp, exp2); } return exp; } Expression parsePathExpr() throws java.io.IOException, SyntaxException { Expression step1; if (curToken == '/' || curToken == SLASHSLASH_TOKEN) { Declaration dotDecl = lexical.lookup(DOT_VARNAME, false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -