?? xqparser.java
字號:
Expression dot; if (dotDecl == null) dot = syntaxError("context item is undefined", "XPDY0002"); else dot = new ReferenceExp(DOT_VARNAME, dotDecl); step1 = new ApplyExp(ClassType.make("gnu.xquery.util.NodeUtils") .getDeclaredMethod("rootDocument", 1), new Expression[] { dot } ); int next = skipSpace(nesting != 0); unread(next); if (next < 0 || next == ')' || next == '}') { getRawToken(); return step1; } } else step1 = parseStepExpr(); return parseRelativePathExpr(step1); } /** Returns an expression that evaluates to a Symbol. * The expression will normally be constant * folded to a Symbol, but we cannot do that yet. */ Expression parseNameTest (boolean attribute) throws java.io.IOException, SyntaxException { String local = null, prefix = null; if (curToken == QNAME_TOKEN) { int colon = tokenBufferLength; while (tokenBuffer[--colon] != ':') ; prefix = new String(tokenBuffer, 0, colon); colon++; local = new String(tokenBuffer, colon, tokenBufferLength - colon); } else if (curToken == OP_MUL) { int next = read(); local = ElementType.MATCH_ANY_LOCALNAME; if (next != ':') unread(next); else { next = read(); if (next < 0) eofError("unexpected end-of-file after '*:'"); if (XName.isNameStart((char) next)) { unread(); getRawToken(); if (curToken != NCNAME_TOKEN) syntaxError("invalid name test"); else local = new String(tokenBuffer, 0, tokenBufferLength) .intern(); } else if (next != '*') syntaxError("missing local-name after '*:'"); } return QuoteExp.getInstance(new Symbol(null, local)); } else if (curToken == NCNAME_TOKEN) { local = new String(tokenBuffer, 0, tokenBufferLength); if (attribute) return new QuoteExp(Namespace.EmptyNamespace.getSymbol(local.intern())); prefix = null; } else if (curToken == NCNAME_COLON_TOKEN) prefix = new String(tokenBuffer, 0, tokenBufferLength); int next = read(); if (next != '*') syntaxError("invalid characters after 'NCName:'"); local = ElementType.MATCH_ANY_LOCALNAME; } if (prefix != null) prefix = prefix.intern(); Expression[] args = new Expression[3]; args[0] = new ApplyExp(new ReferenceExp(XQResolveNames.resolvePrefixDecl), new Expression[] { QuoteExp.getInstance(prefix) }); args[1] = new QuoteExp(local == null ? "" : local); args[2] = new QuoteExp(prefix); ApplyExp make = new ApplyExp(Compilation.typeSymbol .getDeclaredMethod("make", 3), args); make.setFlag(ApplyExp.INLINE_IF_CONSTANT); return make; } Expression parseNodeTest(int axis) throws java.io.IOException, SyntaxException { int token = peekOperand(); Expression[] args = new Expression[1]; Expression etype = parseMaybeKindTest(); if (etype != null) { args[0] = etype; } else if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN || curToken == NCNAME_COLON_TOKEN || curToken == OP_MUL) { args[0] = makeNamedNodeType(axis == AXIS_ATTRIBUTE, parseNameTest(axis == AXIS_ATTRIBUTE) ); } else if (axis >= 0) return syntaxError("unsupported axis '"+axisNames[axis]+"::'"); else return null; Declaration dotDecl = lexical.lookup(DOT_VARNAME, false); Expression dot; if (dotDecl == null) dot = syntaxError("node test when context item is undefined", "XPDY0002"); else dot = new ReferenceExp(DOT_VARNAME, dotDecl); if (etype == null) getRawToken(); Expression makeAxisStep; if (axis == AXIS_CHILD || axis == -1) makeAxisStep = makeChildAxisStep; else if (axis == AXIS_DESCENDANT) makeAxisStep = makeDescendantAxisStep; else { String axisName; switch (axis) { case AXIS_DESCENDANT_OR_SELF: axisName = "DescendantOrSelf"; break; case AXIS_SELF: axisName = "Self"; break; case AXIS_PARENT: axisName = "Parent"; break; case AXIS_ANCESTOR: axisName = "Ancestor"; break; case AXIS_ANCESTOR_OR_SELF: axisName = "AncestorOrSelf"; break; case AXIS_FOLLOWING: axisName = "Following"; break; case AXIS_FOLLOWING_SIBLING: axisName = "FollowingSibling"; break; case AXIS_PRECEDING: axisName = "Preceding"; break; case AXIS_PRECEDING_SIBLING: axisName = "PrecedingSibling"; break; case AXIS_ATTRIBUTE: axisName = "Attribute"; break; default: throw new Error(); } makeAxisStep = QuoteExp.getInstance(new PrimProcedure ("gnu.kawa.xml."+axisName+"Axis", "make", 1)); } ApplyExp mkAxis = new ApplyExp(makeAxisStep, args); mkAxis.setFlag(ApplyExp.INLINE_IF_CONSTANT); return new ApplyExp(mkAxis, new Expression[] { dot }); } public static QuoteExp makeChildAxisStep = QuoteExp.getInstance(new PrimProcedure("gnu.kawa.xml.ChildAxis", "make", 1)); public static QuoteExp makeDescendantAxisStep = QuoteExp.getInstance(new PrimProcedure("gnu.kawa.xml.DescendantAxis", "make", 1)); Expression parseRelativePathExpr(Expression exp) throws java.io.IOException, SyntaxException { // If the previous operator was '//', then the corresponding E1. Expression beforeSlashSlash = null; while (curToken == '/' || curToken == SLASHSLASH_TOKEN) { boolean descendants = curToken == SLASHSLASH_TOKEN; LambdaExp lexp = new LambdaExp(3); Declaration dotDecl = lexp.addDeclaration(DOT_VARNAME); dotDecl.setFlag(Declaration.IS_SINGLE_VALUE); dotDecl.setType(NodeType.anyNodeTest); dotDecl.noteValue (null); // Does not have a known value. lexp.addDeclaration(POSITION_VARNAME, LangPrimType.intType); lexp.addDeclaration(LAST_VARNAME, LangPrimType.intType); comp.push(lexp); if (descendants) { curToken = '/'; Expression dot = new ReferenceExp(DOT_VARNAME, dotDecl); Expression[] args = { dot }; TreeScanner op = DescendantOrSelfAxis.anyNode; lexp.body = new ApplyExp(op, args); beforeSlashSlash = exp; } else { getRawToken(); Expression exp2 = parseStepExpr(); // Optimize: 'E1//child::TEST' to 'E1/descendant::TEST' Expression func; ApplyExp aexp; if (beforeSlashSlash != null && exp2 instanceof ApplyExp && (func = ((ApplyExp) exp2).getFunction()) instanceof ApplyExp && (aexp = (ApplyExp) func).getFunction() == makeChildAxisStep) { aexp.setFunction(makeDescendantAxisStep); exp = beforeSlashSlash; } lexp.body = exp2; beforeSlashSlash = null; } comp.pop(lexp); /* if (lexp.body instanceof ApplyExp) { // Optimize the case of a simple name step. ApplyExp aexp = (ApplyExp) lexp.body; Expression func = aexp.getFunction(); Expression[] args = aexp.getArgs(); if (false && func == funcNamedChildren && args.length==2 && args[0] instanceof ReferenceExp && ((ReferenceExp) args[0]).getBinding() == decl) { args[0] = exp; if (descendants) func = funcNamedDescendants; exp = new ApplyExp (func, args); handled = true; } else if (func == funcForwardFilter && args.length==2 && args[0] instanceof ApplyExp && descendants) { ApplyExp xapp = (ApplyExp) args[0]; Expression[] xargs = xapp.getArgs(); if (xapp.getFunction() == funcNamedChildren && xargs.length == 2 && ((ReferenceExp) xargs[0]).getBinding() == decl) { xapp.setFunction(funcNamedDescendants); } } } */ Expression[] args = new Expression[] { exp, lexp }; exp = new ApplyExp(RelativeStep.relativeStep, args); } return exp; } Expression parseStepExpr() throws java.io.IOException, SyntaxException { int axis; if (curToken == '.' || curToken == DOTDOT_TOKEN) { axis = curToken == '.' ? AXIS_SELF : AXIS_PARENT; getRawToken(); Declaration dotDecl = lexical.lookup(DOT_VARNAME, false); Expression exp; if (dotDecl == null) exp = syntaxError("context item is undefined", "XPDY0002"); else exp = new ReferenceExp(DOT_VARNAME, dotDecl); if (axis == AXIS_PARENT) { Expression[] args = { exp }; exp = new ApplyExp(ParentAxis.make(NodeType.anyNodeTest), args); } // Note that '..' is an AbbrevReverseStep, // but '.' is a FilterExpr - and hence not a valid ForwardStep. return parseStepQualifiers(exp, axis == AXIS_SELF ? -1 : axis); } axis = peekOperand() - OP_AXIS_FIRST; Expression unqualifiedStep; if (axis >= 0 && axis < COUNT_OP_AXIS) { getRawToken(); unqualifiedStep = parseNodeTest(axis); } else if (curToken == '@') { getRawToken(); axis = AXIS_ATTRIBUTE; unqualifiedStep = parseNodeTest(axis); } else if (curToken == OP_ATTRIBUTE) { axis = AXIS_ATTRIBUTE; unqualifiedStep = parseNodeTest(axis); } else { unqualifiedStep = parseNodeTest(-1); if (unqualifiedStep != null) { axis = AXIS_CHILD; } else { axis = -1; unqualifiedStep = parsePrimaryExpr(); } } return parseStepQualifiers(unqualifiedStep, axis); } Expression parseStepQualifiers(Expression exp, int axis) throws java.io.IOException, SyntaxException { for (;;) { if (curToken == '[') { int startLine = getLineNumber() + 1; int startColumn = getColumnNumber() + 1; int saveSeenPosition = seenPosition; int saveSawLast = seenLast; getRawToken(); LambdaExp lexp = new LambdaExp(3); maybeSetLine(lexp, startLine, startColumn); Declaration dot = lexp.addDeclaration(DOT_VARNAME); if (axis >= 0) dot.setType(NodeType.anyNodeTest); else dot.setType(SingletonType.getInstance()); lexp.addDeclaration(POSITION_VARNAME, Type.int_type); lexp.addDeclaration(LAST_VARNAME, Type.int_type); comp.push(lexp); dot.noteValue(null); Expression cond = parseExprSequence(']', false); if (curToken == EOF_TOKEN) eofError("missing ']' - unexpected end-of-file"); char kind; Procedure valuesFilter; if (axis < 0) { kind = 'P'; valuesFilter = ValuesFilter.exprFilter; } else if (axis == AXIS_ANCESTOR || axis == AXIS_ANCESTOR_OR_SELF || axis == AXIS_PARENT || axis == AXIS_PRECEDING || axis == AXIS_PRECEDING_SIBLING) { kind = 'R'; valuesFilter = ValuesFilter.reverseFilter; } else { kind = 'F'; valuesFilter = ValuesFilter.forwardFilter; } /*) boolean sawPosition = seenPosition > saveSeenPosition; boolean sawLast = seenLast > saveSeenLast; */ maybeSetLine(cond, startLine, startColumn); comp.pop(lexp); lexp.body = cond; getRawToken(); Expression[] args = { exp, lexp }; exp = new ApplyExp(valuesFilter, args); } /* else if (curToken == ARROW_TOKEN) ...; */ else { return exp; } } } /** * Parse a PrimaryExpr. * @return an Expression. */ Expression parsePrimaryExpr() throws java.io.IOException, SyntaxException { Expression exp = parseMaybePrimaryExpr(); if (exp == null) { exp = syntaxError("missing expression"); if (curToken != EOF_TOKEN) getRawToken(); return exp; } return exp; } void parseEntityOrCharRef () throws java.io.IOException, SyntaxException { int next = read(); if (next == '#') { int base; next = read(); if (next == 'x') { base = 16; next = read(); } else base = 10; int value = 0; while (next >= 0) { char ch = (char) next; int digit = Character.digit((char) ch, base); if (digit < 0) break; if (value >= 0x8000000) break; // Overflow likely. value = value * base; value += digit; next = read(); } if (next != ';') { unread(); error("invalid character reference"); } // See definition of 'Char' in XML 1.1 2nd ed Specification. else if ((value > 0 && value <= 0xD7FF) || (value >= 0xE000 && value <= 0xFFFD) || (value >= 0x10000 && value <= 0x10FFFF)) tokenBufferAppend(value); else error('e', "invalid character value "+value, "XQST0090"); } else { int saveLength = tokenBufferLength; while (next >= 0) { char ch = (char) next; if (! XName.isNamePart(ch)) break; tokenBufferAppend(ch); next = read(); } if (next != ';') { unread(); error("invalid entity reference"); return; } String ref = new String(tokenBuffer, saveLength, tokenBufferLength - saveLength); tokenBufferLength = saveLength; appendNamedEntity(ref); } } /** C
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -