📄 parser.java
字号:
int pos = S.pos(); S.nextToken(); odStack[top] = topOp == INSTANCEOF ? type() : term3(); while (top > 0 && prec(topOp) >= prec(S.token())) { odStack[top-1] = makeOp(pos, topOp, odStack[top-1], odStack[top]); top--; topOp = opStack[top]; } } assert top == 0; t = odStack[0]; if (t.getTag() == JCTree.PLUS) { StringBuffer buf = foldStrings(t); if (buf != null) { t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString())); } } odStackSupply.elems = savedOd; // optimization opStackSupply.elems = savedOp; // optimization return t; }//where /** Construct a binary or type test node. */ private JCExpression makeOp(int pos, Token topOp, JCExpression od1, JCExpression od2) { if (topOp == INSTANCEOF) { return F.at(pos).TypeTest(od1, od2); } else { return F.at(pos).Binary(optag(topOp), od1, od2); } } /** If tree is a concatenation of string literals, replace it * by a single literal representing the concatenated string. */ protected StringBuffer foldStrings(JCTree tree) { List<String> buf = List.nil(); while (true) { if (tree.getTag() == JCTree.LITERAL) { JCLiteral lit = (JCLiteral) tree; if (lit.typetag == TypeTags.CLASS) { StringBuffer sbuf = new StringBuffer((String)lit.value); while (buf.nonEmpty()) { sbuf.append(buf.head); buf = buf.tail; } return sbuf; } } else if (tree.getTag() == JCTree.PLUS) { JCBinary op = (JCBinary)tree; if (op.rhs.getTag() == JCTree.LITERAL) { JCLiteral lit = (JCLiteral) op.rhs; if (lit.typetag == TypeTags.CLASS) { buf = buf.prepend((String) lit.value); tree = op.lhs; continue; } } } return null; } } /** optimization: To save allocating a new operand/operator stack * for every binary operation, we use supplys. */ ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>(); ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>(); private JCExpression[] newOdStack() { if (odStackSupply.elems == odStackSupply.last) odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]); JCExpression[] odStack = odStackSupply.elems.head; odStackSupply.elems = odStackSupply.elems.tail; return odStack; } private Token[] newOpStack() { if (opStackSupply.elems == opStackSupply.last) opStackSupply.append(new Token[infixPrecedenceLevels + 1]); Token[] opStack = opStackSupply.elems.head; opStackSupply.elems = opStackSupply.elems.tail; return opStack; } /** Expression3 = PrefixOp Expression3 * | "(" Expr | TypeNoParams ")" Expression3 * | Primary {Selector} {PostfixOp} * Primary = "(" Expression ")" * | Literal * | [TypeArguments] THIS [Arguments] * | [TypeArguments] SUPER SuperSuffix * | NEW [TypeArguments] Creator * | Ident { "." Ident } * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) * | Arguments * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) * ] * | BasicType BracketsOpt "." CLASS * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" * PostfixOp = "++" | "--" * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt * | BasicType * TypeNoParams3 = Ident { "." Ident } BracketsOpt * Selector = "." [TypeArguments] Ident [Arguments] * | "." THIS * | "." [TypeArguments] SUPER SuperSuffix * | "." NEW [TypeArguments] InnerCreator * | "[" Expression "]" * TypeSelector = "." Ident [TypeArguments] * SuperSuffix = Arguments | "." Ident [Arguments] */ protected JCExpression term3() { int pos = S.pos(); JCExpression t; List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); switch (S.token()) { case QUES: if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { mode = TYPE; return typeArgument(); } else return illegal(); case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: if (typeArgs == null && (mode & EXPR) != 0) { Token token = S.token(); S.nextToken(); mode = EXPR; if (token == SUB && (S.token() == INTLITERAL || S.token() == LONGLITERAL) && S.radix() == 10) { mode = EXPR; t = literal(names.hyphen); } else { t = term3(); return F.at(pos).Unary(unoptag(token), t); } } else return illegal(); break; case LPAREN: if (typeArgs == null && (mode & EXPR) != 0) { S.nextToken(); mode = EXPR | TYPE | NOPARAMS; t = term3(); if ((mode & TYPE) != 0 && S.token() == LT) { // Could be a cast to a parameterized type int op = JCTree.LT; int pos1 = S.pos(); S.nextToken(); mode &= (EXPR | TYPE); mode |= TYPEARG; JCExpression t1 = term3(); if ((mode & TYPE) != 0 && (S.token() == COMMA || S.token() == GT)) { mode = TYPE; ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); args.append(t1); while (S.token() == COMMA) { S.nextToken(); args.append(typeArgument()); } accept(GT); t = F.at(pos1).TypeApply(t, args.toList()); checkGenerics(); t = bracketsOpt(toP(t)); } else if ((mode & EXPR) != 0) { mode = EXPR; t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec)); t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); } else { accept(GT); } } else { t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); } accept(RPAREN); lastmode = mode; mode = EXPR; if ((lastmode & EXPR) == 0) { JCExpression t1 = term3(); return F.at(pos).TypeCast(t, t1); } else if ((lastmode & TYPE) != 0) { switch (S.token()) { /*case PLUSPLUS: case SUBSUB: */ case BANG: case TILDE: case LPAREN: case THIS: case SUPER: case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: case TRUE: case FALSE: case NULL: case NEW: case IDENTIFIER: case ASSERT: case ENUM: case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: JCExpression t1 = term3(); return F.at(pos).TypeCast(t, t1); } } } else return illegal(); t = toP(F.at(pos).Parens(t)); break; case THIS: if ((mode & EXPR) != 0) { mode = EXPR; t = to(F.at(pos).Ident(names._this)); S.nextToken(); if (typeArgs == null) t = argumentsOpt(null, t); else t = arguments(typeArgs, t); typeArgs = null; } else return illegal(); break; case SUPER: if ((mode & EXPR) != 0) { mode = EXPR; t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super))); typeArgs = null; } else return illegal(); break; case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: case TRUE: case FALSE: case NULL: if (typeArgs == null && (mode & EXPR) != 0) { mode = EXPR; t = literal(names.empty); } else return illegal(); break; case NEW: if (typeArgs != null) return illegal(); if ((mode & EXPR) != 0) { mode = EXPR; S.nextToken(); if (S.token() == LT) typeArgs = typeArguments(); t = creator(pos, typeArgs); typeArgs = null; } else return illegal(); break; case IDENTIFIER: case ASSERT: case ENUM: if (typeArgs != null) return illegal(); t = toP(F.at(S.pos()).Ident(ident())); loop: while (true) { pos = S.pos(); switch (S.token()) { case LBRACKET: S.nextToken(); if (S.token() == RBRACKET) { S.nextToken(); t = bracketsOpt(t); t = toP(F.at(pos).TypeArray(t)); t = bracketsSuffix(t); } else { if ((mode & EXPR) != 0) { mode = EXPR; JCExpression t1 = term(); t = to(F.at(pos).Indexed(t, t1)); } accept(RBRACKET); } break loop; case LPAREN: if ((mode & EXPR) != 0) { mode = EXPR; t = arguments(typeArgs, t); typeArgs = null; } break loop; case DOT: S.nextToken(); typeArgs = typeArgumentsOpt(EXPR); if ((mode & EXPR) != 0) { switch (S.token()) { case CLASS: if (typeArgs != null) return illegal(); mode = EXPR; t = to(F.at(pos).Select(t, names._class)); S.nextToken(); break loop; case THIS: if (typeArgs != null) return illegal(); mode = EXPR; t = to(F.at(pos).Select(t, names._this)); S.nextToken(); break loop; case SUPER: mode = EXPR; t = to(F.at(pos).Select(t, names._super)); t = superSuffix(typeArgs, t); typeArgs = null; break loop; case NEW: if (typeArgs != null) return illegal(); mode = EXPR; int pos1 = S.pos(); S.nextToken(); if (S.token() == LT) typeArgs = typeArguments(); t = innerCreator(pos1, typeArgs, t); typeArgs = null; break loop; } } // typeArgs saved for next loop iteration. t = toP(F.at(pos).Select(t, ident())); break; default: break loop; } } if (typeArgs != null) illegal(); t = typeArgumentsOpt(t); break; case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: if (typeArgs != null) illegal(); t = bracketsSuffix(bracketsOpt(basicType())); break; case VOID: if (typeArgs != null) illegal(); if ((mode & EXPR) != 0) { S.nextToken(); if (S.token() == DOT) { JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); t = bracketsSuffix(ti); } else { return illegal(pos); } } else { return illegal(); } break; default: return illegal(); } if (typeArgs != null) illegal(); while (true) { int pos1 = S.pos(); if (S.token() == LBRACKET) { S.nextToken(); if ((mode & TYPE) != 0) { int oldmode = mode; mode = TYPE; if (S.token() == RBRACKET) { S.nextToken(); t = bracketsOpt(t); t = toP(F.at(pos1).TypeArray(t)); return t; } mode = oldmode; } if ((mode & EXPR) != 0) { mode = EXPR; JCExpression t1 = term(); t = to(F.at(pos1).Indexed(t, t1)); } accept(RBRACKET); } else if (S.token() == DOT) { S.nextToken(); typeArgs = typeArgumentsOpt(EXPR); if (S.token() == SUPER && (mode & EXPR) != 0) { mode = EXPR; t = to(F.at(pos1).Select(t, names._super)); S.nextToken();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -