📄 parser.java
字号:
S.nextToken(); if (S.token() == RBRACE) break; elems.append(variableInitializer()); } } accept(RBRACE); return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList())); } /** VariableInitializer = ArrayInitializer | Expression */ public JCExpression variableInitializer() { return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : expression(); } /** ParExpression = "(" Expression ")" */ JCExpression parExpression() { accept(LPAREN); JCExpression t = expression(); accept(RPAREN); return t; } /** Block = "{" BlockStatements "}" */ JCBlock block(int pos, long flags) { accept(LBRACE); List<JCStatement> stats = blockStatements(); JCBlock t = F.at(pos).Block(flags, stats); while (S.token() == CASE || S.token() == DEFAULT) { syntaxError("orphaned", keywords.token2string(S.token())); switchBlockStatementGroups(); } // the Block node has a field "endpos" for first char of last token, which is // usually but not necessarily the last char of the last token. t.endpos = S.pos(); accept(RBRACE); return toP(t); } public JCBlock block() { return block(S.pos(), 0); } /** BlockStatements = { BlockStatement } * BlockStatement = LocalVariableDeclarationStatement * | ClassOrInterfaceOrEnumDeclaration * | [Ident ":"] Statement * LocalVariableDeclarationStatement * = { FINAL | '@' Annotation } Type VariableDeclarators ";" */ @SuppressWarnings("fallthrough") List<JCStatement> blockStatements() {//todo: skip to anchor on error(?) int lastErrPos = -1; ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); while (true) { int pos = S.pos(); switch (S.token()) { case RBRACE: case CASE: case DEFAULT: case EOF: return stats.toList(); case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: stats.append(statement()); break; case MONKEYS_AT: case FINAL: { String dc = S.docComment(); JCModifiers mods = modifiersOpt(); if (S.token() == INTERFACE || S.token() == CLASS || allowEnums && S.token() == ENUM) { stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); } else { JCExpression t = type(); stats.appendList(variableDeclarators(mods, t, new ListBuffer<JCStatement>())); // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon storeEnd(stats.elems.last(), S.endPos()); accept(SEMI); } break; } case ABSTRACT: case STRICTFP: { String dc = S.docComment(); JCModifiers mods = modifiersOpt(); stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); break; } case INTERFACE: case CLASS: stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), S.docComment())); break; case ENUM: case ASSERT: if (allowEnums && S.token() == ENUM) { log.error(S.pos(), "local.enum"); stats. append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), S.docComment())); break; } else if (allowAsserts && S.token() == ASSERT) { stats.append(statement()); break; } /* fall through to default */ default: Name name = S.name(); JCExpression t = term(EXPR | TYPE); if (S.token() == COLON && t.getTag() == JCTree.IDENT) { S.nextToken(); JCStatement stat = statement(); stats.append(F.at(pos).Labelled(name, stat)); } else if ((lastmode & TYPE) != 0 && (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) { pos = S.pos(); JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); F.at(pos); stats.appendList(variableDeclarators(mods, t, new ListBuffer<JCStatement>())); // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon storeEnd(stats.elems.last(), S.endPos()); accept(SEMI); } else { // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon stats.append(to(F.at(pos).Exec(checkExprStat(t)))); accept(SEMI); } } // error recovery if (S.pos() == lastErrPos) return stats.toList(); if (S.pos() <= errorEndPos) { skip(false, true, true, true); lastErrPos = S.pos(); } // ensure no dangling /** @deprecated */ active S.resetDeprecatedFlag(); } } /** Statement = * Block * | IF ParExpression Statement [ELSE Statement] * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement * | FOR "(" FormalParameter : Expression ")" Statement * | WHILE ParExpression Statement * | DO Statement WHILE ParExpression ";" * | TRY Block ( Catches | [Catches] FinallyPart ) * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" * | SYNCHRONIZED ParExpression Block * | RETURN [Expression] ";" * | THROW Expression ";" * | BREAK [Ident] ";" * | CONTINUE [Ident] ";" * | ASSERT Expression [ ":" Expression ] ";" * | ";" * | ExpressionStatement * | Ident ":" Statement */ @SuppressWarnings("fallthrough") public JCStatement statement() { int pos = S.pos(); switch (S.token()) { case LBRACE: return block(); case IF: { S.nextToken(); JCExpression cond = parExpression(); JCStatement thenpart = statement(); JCStatement elsepart = null; if (S.token() == ELSE) { S.nextToken(); elsepart = statement(); } return F.at(pos).If(cond, thenpart, elsepart); } case FOR: { S.nextToken(); accept(LPAREN); List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); if (inits.length() == 1 && inits.head.getTag() == JCTree.VARDEF && ((JCVariableDecl) inits.head).init == null && S.token() == COLON) { checkForeach(); JCVariableDecl var = (JCVariableDecl)inits.head; accept(COLON); JCExpression expr = expression(); accept(RPAREN); JCStatement body = statement(); return F.at(pos).ForeachLoop(var, expr, body); } else { accept(SEMI); JCExpression cond = S.token() == SEMI ? null : expression(); accept(SEMI); List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); accept(RPAREN); JCStatement body = statement(); return F.at(pos).ForLoop(inits, cond, steps, body); } } case WHILE: { S.nextToken(); JCExpression cond = parExpression(); JCStatement body = statement(); return F.at(pos).WhileLoop(cond, body); } case DO: { S.nextToken(); JCStatement body = statement(); accept(WHILE); JCExpression cond = parExpression(); JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond)); accept(SEMI); return t; } case TRY: { S.nextToken(); JCBlock body = block(); ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); JCBlock finalizer = null; if (S.token() == CATCH || S.token() == FINALLY) { while (S.token() == CATCH) catchers.append(catchClause()); if (S.token() == FINALLY) { S.nextToken(); finalizer = block(); } } else { log.error(pos, "try.without.catch.or.finally"); } return F.at(pos).Try(body, catchers.toList(), finalizer); } case SWITCH: { S.nextToken(); JCExpression selector = parExpression(); accept(LBRACE); List<JCCase> cases = switchBlockStatementGroups(); JCSwitch t = to(F.at(pos).Switch(selector, cases)); accept(RBRACE); return t; } case SYNCHRONIZED: { S.nextToken(); JCExpression lock = parExpression(); JCBlock body = block(); return F.at(pos).Synchronized(lock, body); } case RETURN: { S.nextToken(); JCExpression result = S.token() == SEMI ? null : expression(); JCReturn t = to(F.at(pos).Return(result)); accept(SEMI); return t; } case THROW: { S.nextToken(); JCExpression exc = expression(); JCThrow t = to(F.at(pos).Throw(exc)); accept(SEMI); return t; } case BREAK: { S.nextToken(); Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; JCBreak t = to(F.at(pos).Break(label)); accept(SEMI); return t; } case CONTINUE: { S.nextToken(); Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; JCContinue t = to(F.at(pos).Continue(label)); accept(SEMI); return t; } case SEMI: S.nextToken(); return toP(F.at(pos).Skip()); case ELSE: return toP(F.Exec(syntaxError("else.without.if"))); case FINALLY: return toP(F.Exec(syntaxError("finally.without.try"))); case CATCH: return toP(F.Exec(syntaxError("catch.without.try"))); case ASSERT: { if (allowAsserts && S.token() == ASSERT) { S.nextToken(); JCExpression assertion = expression(); JCExpression message = null; if (S.token() == COLON) { S.nextToken(); message = expression(); } JCAssert t = to(F.at(pos).Assert(assertion, message)); accept(SEMI); return t; } /* else fall through to default case */ } case ENUM: default: Name name = S.name(); JCExpression expr = expression(); if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { S.nextToken(); JCStatement stat = statement(); return F.at(pos).Labelled(name, stat); } else { // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); accept(SEMI); return stat; } } } /** CatchClause = CATCH "(" FormalParameter ")" Block */ JCCatch catchClause() { int pos = S.pos(); accept(CATCH); accept(LPAREN); JCVariableDecl formal = variableDeclaratorId(optFinal(Flags.PARAMETER), qualident()); accept(RPAREN); JCBlock body = block(); return F.at(pos).Catch(formal, body); } /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } * SwitchBlockStatementGroup = SwitchLabel BlockStatements * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" */ List<JCCase> switchBlockStatementGroups() { ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); while (true) { int pos = S.pos(); switch (S.token()) { case CASE: { S.nextToken(); JCExpression pat = expression(); accept(COLON); List<JCStatement> stats = blockStatements(); JCCase c = F.at(pos).Case(pat, stats); if (stats.isEmpty()) storeEnd(c, S.prevEndPos()); cases.append(c); break; } case DEFAULT: { S.nextToken(); accept(COLON); List<JCStatement> stats = blockStatements(); JCCase c = F.at(pos).Case(null, stats); if (stats.isEmpty()) storeEnd(c, S.prevEndPos()); cases.append(c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -