📄 parser.java
字号:
Tree termRest(Tree t) {
switch (S.token) {
case EQ:
{
int pos = S.pos;
S.nextToken();
mode = EXPR;
Tree t1 = term();
return F.at(pos).Assign(t, t1);
}
case PLUSEQ:
case SUBEQ:
case STAREQ:
case SLASHEQ:
case PERCENTEQ:
case AMPEQ:
case BAREQ:
case CARETEQ:
case LTLTEQ:
case GTGTEQ:
case GTGTGTEQ:
int pos = S.pos;
int token = S.token;
S.nextToken();
mode = EXPR;
Tree t1 = term();
return F.at(pos).Assignop(optag(token), t, t1);
default:
return t;
}
}
/**
* Expression1 = Expression2 [Expression1Rest]
* Type1 = Type2
* TypeNoParams1 = TypeNoParams2
*/
Tree term1() {
Tree t = term2();
if ((mode & EXPR) != 0 & S.token == QUES) {
mode = EXPR;
return term1Rest(t);
} else {
return t;
}
}
/**
* Expression1Rest = ["?" Expression ":" Expression1]
*/
Tree term1Rest(Tree t) {
if (S.token == QUES) {
int pos = S.pos;
S.nextToken();
Tree t1 = term();
accept(COLON);
Tree t2 = term1();
return F.at(pos).Conditional(t, t1, t2);
} else {
return t;
}
}
/**
* Expression2 = Expression3 [Expression2Rest]
* Type2 = Type3
* TypeNoParams2 = TypeNoParams3
*/
Tree term2() {
Tree t = term3();
if ((mode & EXPR) != 0 && prec(S.token) >= TreeInfo.orPrec) {
mode = EXPR;
return term2Rest(t, TreeInfo.orPrec);
} else {
return t;
}
}
Tree term2Rest(Tree t, int minprec) {
List savedOd = odStackSupply.elems;
Tree[] odStack = newOdStack();
List savedOp = opStackSupply.elems;
int[] opStack = newOpStack();
int top = 0;
odStack[0] = t;
int startPos = S.pos;
int topOp = ERROR;
while (prec(S.token) >= minprec) {
opStack[top] = topOp;
top++;
topOp = S.token;
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.tag == Tree.PLUS) {
StringBuffer buf = foldStrings(t);
if (buf != null) {
t = F.at(startPos).Literal(Type.CLASS, buf.toString());
}
}
odStackSupply.elems = savedOd;
opStackSupply.elems = savedOp;
return t;
}
/**
* Construct a binary or type test node.
*/
private Tree makeOp(int pos, int topOp, Tree od1, Tree od2) {
if (topOp == INSTANCEOF) {
return F.at(pos).TypeTest(od1, od2);
} else {
return F.at(pos).Binary(optag(topOp), od1, od2);
}
}
/**
* The empty List<String>.
*/
private static List emptyStringList = new List();
/**
* If tree is a concatenation of string literals, replace it
* by a single literal representing the concatenated string.
*/
private static StringBuffer foldStrings(Tree tree) {
List buf = emptyStringList;
while (true) {
if (tree.tag == Tree.LITERAL) {
Literal lit = (Literal) tree;
if (lit.typetag == Type.CLASS) {
StringBuffer sbuf = new StringBuffer((String) lit.value);
while (buf.nonEmpty()) {
sbuf.append((String) buf.head);
buf = buf.tail;
}
return sbuf;
}
} else if (tree.tag == Tree.PLUS) {
Binary op = (Binary) tree;
if (op.rhs.tag == Tree.LITERAL) {
Literal lit = (Literal) op.rhs;
if (lit.typetag == Type.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 odStackSupply = new ListBuffer();
ListBuffer opStackSupply = new ListBuffer();
private Tree[] newOdStack() {
if (odStackSupply.elems == odStackSupply.last)
odStackSupply.append(new Tree[infixPrecedenceLevels + 1]);
Tree[] odStack = (Tree[]) odStackSupply.elems.head;
odStackSupply.elems = odStackSupply.elems.tail;
return odStack;
}
private int[] newOpStack() {
if (opStackSupply.elems == opStackSupply.last)
opStackSupply.append(new int[infixPrecedenceLevels + 1]);
int[] opStack = (int[]) opStackSupply.elems.head;
opStackSupply.elems = opStackSupply.elems.tail;
return opStack;
}
/**
* Expression3 = PrefixOp Expression3
* | "(" Expr | TypeNoParams ")" Expression3
* | Primary {Selector} {PostfixOp}
* Primary = "(" Expression ")"
* | THIS [Arguments]
* | SUPER SuperSuffix
* | Literal
* | NEW Creator
* | Ident { "." Ident }
* [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
* | Arguments
* | "." ( CLASS | THIS | SUPER Arguments | NEW InnerCreator )
* ]
* | BasicType BracketsOpt "." CLASS
* PrefixOp = "++" | "--" | "!" | "~" | "+" | "-"
* PostfixOp = "++" | "--"
* Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
* | BasicType
* TypeNoParams3 = Ident { "." Ident } BracketsOpt
* Selector = "." Ident [Arguments]
* | "." THIS
* | "." SUPER SuperSuffix
* | "." NEW InnerCreator
* | "[" Expression "]"
* TypeSelector = "." Ident [TypeArguments]
* SuperSuffix = Arguments | "." Ident [Arguments]
*/
Tree term3() {
int pos = S.pos;
Tree t;
switch (S.token) {
case PLUSPLUS:
case SUBSUB:
case BANG:
case TILDE:
case PLUS:
case SUB:
if ((mode & EXPR) != 0) {
mode = EXPR;
int token = S.token;
S.nextToken();
if (token == SUB &&
(S.token == INTLITERAL || S.token == LONGLITERAL) &&
S.radix == 10) {
t = literal(names.hyphen);
} else {
t = term3();
return F.at(pos).Unary(unoptag(token), t);
}
} else
return illegal();
break;
case LPAREN:
if ((mode & EXPR) != 0) {
S.nextToken();
mode = EXPR | TYPE | NOPARAMS;
t = term3();
t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
accept(RPAREN);
lastmode = mode;
mode = EXPR;
if ((lastmode & EXPR) == 0) {
Tree t1 = term3();
return F.at(pos).TypeCast(t, t1);
} else if ((lastmode & TYPE) != 0) {
switch (S.token) {
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 BYTE:
case SHORT:
case CHAR:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
case BOOLEAN:
case VOID:
Tree t1 = term3();
return F.at(pos).TypeCast(t, t1);
}
}
} else
return illegal();
t = F.at(pos).Parens(t);
break;
case THIS:
if ((mode & EXPR) != 0) {
mode = EXPR;
t = F.at(pos).Ident(names._this);
S.nextToken();
t = argumentsOpt(t);
} else
return illegal();
break;
case SUPER:
if ((mode & EXPR) != 0) {
mode = EXPR;
t = superSuffix(F.at(pos).Ident(names._super));
} else
return illegal();
break;
case INTLITERAL:
case LONGLITERAL:
case FLOATLITERAL:
case DOUBLELITERAL:
case CHARLITERAL:
case STRINGLITERAL:
case TRUE:
case FALSE:
case NULL:
if ((mode & EXPR) != 0) {
mode = EXPR;
t = literal(names.empty);
} else
return illegal();
break;
case NEW:
if ((mode & EXPR) != 0) {
mode = EXPR;
S.nextToken();
t = creator(pos);
} else
return illegal();
break;
case IDENTIFIER:
case ASSERT:
t = 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 = bracketsSuffix(bracketsOpt(F.at(pos).TypeArray(t)));
} else {
if ((mode & EXPR) != 0) {
mode = EXPR;
Tree t1 = term();
t = F.at(pos).Indexed(t, t1);
}
accept(RBRACKET);
}
break loop;
case LPAREN:
if ((mode & EXPR) != 0) {
mode = EXPR;
t = arguments(t);
}
break loop;
case DOT:
S.nextToken();
if ((mode & EXPR) != 0) {
switch (S.token) {
case CLASS:
mode = EXPR;
t = F.at(pos).Select(t, names._class);
S.nextToken();
break loop;
case THIS:
mode = EXPR;
t = F.at(pos).Select(t, names._this);
S.nextToken();
break loop;
case SUPER:
mode = EXPR;
t = superSuffix(F.at(pos).Select(t, names._super));
break loop;
case NEW:
mode = EXPR;
int pos1 = S.pos;
S.nextToken();
t = innerCreator(pos1, t);
break loop;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -