📄 parser.java
字号:
(S.token == IDENTIFIER || S.token == ASSERT)) {
stats.appendList(variableDeclarators(0, t));
accept(SEMI);
} else {
stats.append(F.at(pos).Exec(checkExprStat(t)));
accept(SEMI);
}
}
}
}
/**
* Statement =
* Block
* | IF ParExpression Statement [ELSE Statement]
* | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" 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
*/
Tree statement() {
int pos = S.pos;
switch (S.token) {
case LBRACE:
return block();
case IF:
{
S.nextToken();
Tree cond = parExpression();
Tree thenpart = statement();
Tree 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 inits = S.token == SEMI ? Tree.emptyList : forInit();
accept(SEMI);
Tree cond = S.token == SEMI ? null : expression();
accept(SEMI);
List steps = S.token == RPAREN ? Tree.emptyList : forUpdate();
accept(RPAREN);
Tree body = statement();
return F.at(pos).ForLoop(inits, cond, steps, body);
}
case WHILE:
{
S.nextToken();
Tree cond = parExpression();
Tree body = statement();
return F.at(pos).WhileLoop(cond, body);
}
case DO:
{
S.nextToken();
Tree body = statement();
accept(WHILE);
Tree cond = parExpression();
Tree t = F.at(pos).DoLoop(body, cond);
if (genEndPos)
endPositions.put(t, new Integer(S.endPos));
accept(SEMI);
return t;
}
case TRY:
{
S.nextToken();
Tree body = block();
ListBuffer catchers = new ListBuffer();
Tree 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();
Tree selector = parExpression();
accept(LBRACE);
List cases = switchBlockStatementGroups();
Tree t = F.at(pos).Switch(selector, cases);
if (genEndPos)
endPositions.put(t, new Integer(S.endPos));
accept(RBRACE);
return t;
}
case SYNCHRONIZED:
{
S.nextToken();
Tree lock = parExpression();
Tree body = block();
return F.at(pos).Synchronized(lock, body);
}
case RETURN:
{
S.nextToken();
Tree result = S.token == SEMI ? null : expression();
Tree t = F.at(pos).Return(result);
if (genEndPos)
endPositions.put(t, new Integer(S.endPos));
accept(SEMI);
return t;
}
case THROW:
{
S.nextToken();
Tree exc = expression();
Tree t = F.at(pos).Throw(exc);
if (genEndPos)
endPositions.put(t, new Integer(S.endPos));
accept(SEMI);
return t;
}
case BREAK:
{
S.nextToken();
Name label = (S.token == IDENTIFIER || S.token == ASSERT) ? ident() :
null;
Tree t = F.at(pos).Break(label);
if (genEndPos)
endPositions.put(t, new Integer(S.prevEndPos));
accept(SEMI);
return t;
}
case CONTINUE:
{
S.nextToken();
Name label = (S.token == IDENTIFIER || S.token == ASSERT) ? ident() :
null;
Tree t = F.at(pos).Continue(label);
if (genEndPos)
endPositions.put(t, new Integer(S.prevEndPos));
accept(SEMI);
return t;
}
case SEMI:
S.nextToken();
return F.at(pos).Skip();
case ELSE:
return syntaxError("else.without.if");
case FINALLY:
return syntaxError("finally.without.try");
case CATCH:
return syntaxError("catch.without.try");
case ASSERT:
{
if (allowAsserts) {
S.nextToken();
Tree assertion = expression();
Tree message = null;
if (S.token == COLON) {
S.nextToken();
message = expression();
}
Tree t = F.at(pos).Assert(assertion, message);
accept(SEMI);
return t;
}
}
default:
Name name = S.name;
Tree expr = expression();
if (S.token == COLON && expr.tag == Tree.IDENT) {
S.nextToken();
Tree stat = statement();
return F.at(pos).Labelled(name, stat);
} else {
Tree stat = F.at(pos).Exec(checkExprStat(expr));
accept(SEMI);
return stat;
}
}
}
/**
* CatchClause = CATCH "(" FormalParameter ")" Block
*/
Catch catchClause() {
int pos = S.pos;
accept(CATCH);
accept(LPAREN);
VarDef formal =
variableDeclaratorId(optFinal() | Flags.PARAMETER, qualident());
accept(RPAREN);
Tree body = block();
return F.at(pos).Catch(formal, body);
}
/**
* SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
* SwitchBlockStatementGroup = SwitchLabel BlockStatements
* SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
*/
List switchBlockStatementGroups() {
ListBuffer cases = new ListBuffer();
while (true) {
int pos = S.pos;
switch (S.token) {
case CASE:
{
S.nextToken();
Tree pat = expression();
accept(COLON);
List stats = blockStatements();
cases.append(F.at(pos).Case(pat, stats));
break;
}
case DEFAULT:
{
S.nextToken();
accept(COLON);
List stats = blockStatements();
cases.append(F.at(pos).Case(null, stats));
break;
}
case RBRACE:
case EOF:
return cases.toList();
default:
S.nextToken();
syntaxError(pos, "case.default.or.right-brace.expected");
}
}
}
/**
* MoreStatementExpressions = { COMMA StatementExpression }
*/
List moreStatementExpressions(int pos, Tree first) {
ListBuffer stats = new ListBuffer();
stats.append(F.at(pos).Exec(checkExprStat(first)));
while (S.token == COMMA) {
S.nextToken();
pos = S.pos;
Tree t = expression();
stats.append(F.at(pos).Exec(checkExprStat(t)));
}
return stats.toList();
}
/**
* ForInit = StatementExpression MoreStatementExpressions
* | [FINAL] Type VariableDeclarators
*/
List forInit() {
int pos = S.pos;
if (S.token == FINAL) {
S.nextToken();
return variableDeclarators(Flags.FINAL, type());
} else {
Tree t = term(EXPR | TYPE);
if ((lastmode & TYPE) != 0 &&
(S.token == IDENTIFIER || S.token == ASSERT))
return variableDeclarators(0, t);
else
return moreStatementExpressions(pos, t);
}
}
/**
* ForUpdate = StatementExpression MoreStatementExpressions
*/
List forUpdate() {
return moreStatementExpressions(S.pos, expression());
}
/**
* ModifiersOpt = { Modifier }
* Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
* | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE
*/
long modifiersOpt() {
long flags = 0;
if (S.deprecatedFlag) {
flags = Flags.DEPRECATED;
S.deprecatedFlag = false;
}
while (true) {
int flag;
switch (S.token) {
case PRIVATE:
flag = Flags.PRIVATE;
break;
case PROTECTED:
flag = Flags.PROTECTED;
break;
case PUBLIC:
flag = Flags.PUBLIC;
break;
case STATIC:
flag = Flags.STATIC;
break;
case TRANSIENT:
flag = Flags.TRANSIENT;
break;
case FINAL:
flag = Flags.FINAL;
break;
case ABSTRACT:
flag = Flags.ABSTRACT;
break;
case NATIVE:
flag = Flags.NATIVE;
break;
case VOLATILE:
flag = Flags.VOLATILE;
break;
case SYNCHRONIZED:
flag = Flags.SYNCHRONIZED;
break;
case STRICTFP:
flag = Flags.STRICTFP;
break;
default:
return flags;
}
if ((flags & flag) != 0)
log.error(S.pos, "repeated.modifier");
flags = flags | flag;
S.nextToken();
}
}
/**
* VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
*/
List variableDeclarators(long flags, Tree type) {
return variableDeclaratorsRest(S.pos, flags, type, ident(), false, null);
}
/**
* VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
* ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
*
* @param reqInit Is an initializer always required?
* @param dc The documentation comment for the variable declarations, or null.
*/
List variableDeclaratorsRest(int pos, long flags, Tree type, Name name,
boolean reqInit, String dc) {
ListBuffer vdefs = new ListBuffer();
vdefs.append(variableDeclaratorRest(pos, flags, type, name, reqInit, dc));
while (S.token == COMMA) {
S.nextToken();
vdefs.append(variableDeclarator(flags, type, reqInit, dc));
}
return vdefs.toList();
}
/**
* VariableDeclarator = Ident VariableDeclaratorRest
* ConstantDeclarator = Ident ConstantDeclaratorRest
*/
VarDef variableDeclarator(long flags, Tree type, boolean reqInit, String dc) {
return variableDeclaratorRest(S.pos, flags, type, ident(), reqInit, dc);
}
/**
* VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
* ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
*
* @param reqInit Is an initializer always required?
* @param dc The documentation comment for the variable declarations, or null.
*/
VarDef variableDeclaratorRest(int pos, long flags, Tree type, Name name,
boolean reqInit, String dc) {
type = bracketsOpt(type);
Tree init = null;
if (S.token == EQ) {
S.nextToken();
init = variableInitializer();
} else if (reqInit)
syntaxError(S.pos, "expected", keywords.token2string(EQ));
VarDef result = F.at(pos).VarDef(flags, name, type, init);
if (genEndPos)
endPositions.put(result, new Integer(S.prevEndPos));
attach(result, dc);
return result;
}
/**
* VariableDeclaratorId = Ident BracketsOpt
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -