📄 parser.java
字号:
/* synchronized.statement : * SYNCHRONIZED "(" expression ")" block.statement */ private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError { int t = lex.get(); // SYNCHRONIZED if (lex.get() != '(') throw new SyntaxError(lex); ASTree expr = parseExpression(tbl); if (lex.get() != ')') throw new SyntaxError(lex); Stmnt body = parseBlock(tbl); return new Stmnt(t, expr, body); } /* try.statement * : TRY block.statement * [ CATCH "(" class.type Identifier ")" block.statement ]* * [ FINALLY block.statement ]* */ private Stmnt parseTry(SymbolTable tbl) throws CompileError { lex.get(); // TRY Stmnt block = parseBlock(tbl); ASTList catchList = null; while (lex.lookAhead() == CATCH) { lex.get(); // CATCH if (lex.get() != '(') throw new SyntaxError(lex); SymbolTable tbl2 = new SymbolTable(tbl); Declarator d = parseFormalParam(tbl2); if (d.getArrayDim() > 0 || d.getType() != CLASS) throw new SyntaxError(lex); if (lex.get() != ')') throw new SyntaxError(lex); Stmnt b = parseBlock(tbl2); catchList = ASTList.append(catchList, new Pair(d, b)); } Stmnt finallyBlock = null; if (lex.lookAhead() == FINALLY) { lex.get(); // FINALLY finallyBlock = parseBlock(tbl); } return Stmnt.make(TRY, block, catchList, finallyBlock); } /* return.statement : RETURN [ expression ] ";" */ private Stmnt parseReturn(SymbolTable tbl) throws CompileError { int t = lex.get(); // RETURN Stmnt s = new Stmnt(t); if (lex.lookAhead() != ';') s.setLeft(parseExpression(tbl)); if (lex.get() != ';') throw new CompileError("; is missing", lex); return s; } /* throw.statement : THROW expression ";" */ private Stmnt parseThrow(SymbolTable tbl) throws CompileError { int t = lex.get(); // THROW ASTree expr = parseExpression(tbl); if (lex.get() != ';') throw new CompileError("; is missing", lex); return new Stmnt(t, expr); } /* break.statement : BREAK [ Identifier ] ";" */ private Stmnt parseBreak(SymbolTable tbl) throws CompileError { return parseContinue(tbl); } /* continue.statement : CONTINUE [ Identifier ] ";" */ private Stmnt parseContinue(SymbolTable tbl) throws CompileError { int t = lex.get(); // CONTINUE Stmnt s = new Stmnt(t); int t2 = lex.get(); if (t2 == Identifier) { s.setLeft(new Symbol(lex.getString())); t2 = lex.get(); } if (t2 != ';') throw new CompileError("; is missing", lex); return s; } /* declaration.or.expression * : [ FINAL ] built-in-type array.dimension declarators * | [ FINAL ] class.type array.dimension declarators * | expression ';' * | expr.list ';' if exprList is true * * Note: FINAL is currently ignored. This must be fixed * in future. */ private Stmnt parseDeclarationOrExpression(SymbolTable tbl, boolean exprList) throws CompileError { int t = lex.lookAhead(); while (t == FINAL) { lex.get(); t = lex.lookAhead(); } if (isBuiltinType(t)) { t = lex.get(); int dim = parseArrayDimension(); return parseDeclarators(tbl, new Declarator(t, dim)); } else if (t == Identifier) { int i = nextIsClassType(0); if (i >= 0) if (lex.lookAhead(i) == Identifier) { ASTList name = parseClassType(tbl); int dim = parseArrayDimension(); return parseDeclarators(tbl, new Declarator(name, dim)); } } Stmnt expr; if (exprList) expr = parseExprList(tbl); else expr = new Stmnt(EXPR, parseExpression(tbl)); if (lex.get() != ';') throw new CompileError("; is missing", lex); return expr; } /* expr.list : ( expression ',')* expression */ private Stmnt parseExprList(SymbolTable tbl) throws CompileError { Stmnt expr = null; for (;;) { Stmnt e = new Stmnt(EXPR, parseExpression(tbl)); expr = (Stmnt)ASTList.concat(expr, new Stmnt(BLOCK, e)); if (lex.lookAhead() == ',') lex.get(); else return expr; } } /* declarators : declarator [ ',' declarator ]* ';' */ private Stmnt parseDeclarators(SymbolTable tbl, Declarator d) throws CompileError { Stmnt decl = null; for (;;) { decl = (Stmnt)ASTList.concat(decl, new Stmnt(DECL, parseDeclarator(tbl, d))); int t = lex.get(); if (t == ';') return decl; else if (t != ',') throw new CompileError("; is missing", lex); } } /* declarator : Identifier array.dimension [ '=' initializer ] */ private Declarator parseDeclarator(SymbolTable tbl, Declarator d) throws CompileError { if (lex.get() != Identifier || d.getType() == VOID) throw new SyntaxError(lex); String name = lex.getString(); Symbol symbol = new Symbol(name); int dim = parseArrayDimension(); ASTree init = null; if (lex.lookAhead() == '=') { lex.get(); init = parseInitializer(tbl); } Declarator decl = d.make(symbol, dim, init); tbl.append(name, decl); return decl; } /* initializer : expression | array.initializer */ private ASTree parseInitializer(SymbolTable tbl) throws CompileError { if (lex.lookAhead() == '{') return parseArrayInitializer(tbl); else return parseExpression(tbl); } /* array.initializer : * '{' (( array.initializer | expression ) ',')* '}' */ private ArrayInit parseArrayInitializer(SymbolTable tbl) throws CompileError { lex.get(); // '{' ASTree expr = parseExpression(tbl); ArrayInit init = new ArrayInit(expr); while (lex.lookAhead() == ',') { lex.get(); expr = parseExpression(tbl); ASTList.append(init, expr); } if (lex.get() != '}') throw new SyntaxError(lex); return init; } /* par.expression : '(' expression ')' */ private ASTree parseParExpression(SymbolTable tbl) throws CompileError { if (lex.get() != '(') throw new SyntaxError(lex); ASTree expr = parseExpression(tbl); if (lex.get() != ')') throw new SyntaxError(lex); return expr; } /* expression : conditional.expr * | conditional.expr assign.op expression (right-to-left) */ public ASTree parseExpression(SymbolTable tbl) throws CompileError { ASTree left = parseConditionalExpr(tbl); if (!isAssignOp(lex.lookAhead())) return left; int t = lex.get(); ASTree right = parseExpression(tbl); return AssignExpr.makeAssign(t, left, right); } private static boolean isAssignOp(int t) { return t == '=' || t == MOD_E || t == AND_E || t == MUL_E || t == PLUS_E || t == MINUS_E || t == DIV_E || t == EXOR_E || t == OR_E || t == LSHIFT_E || t == RSHIFT_E || t == ARSHIFT_E; } /* conditional.expr (right-to-left) * : logical.or.expr [ '?' expression ':' conditional.expr ] */ private ASTree parseConditionalExpr(SymbolTable tbl) throws CompileError { ASTree cond = parseBinaryExpr(tbl); if (lex.lookAhead() == '?') { lex.get(); ASTree thenExpr = parseExpression(tbl); if (lex.get() != ':') throw new CompileError(": is missing", lex); ASTree elseExpr = parseExpression(tbl); return new CondExpr(cond, thenExpr, elseExpr); } else return cond; } /* logical.or.expr 10 (operator precedence) * : logical.and.expr * | logical.or.expr OROR logical.and.expr left-to-right * * logical.and.expr 9 * : inclusive.or.expr * | logical.and.expr ANDAND inclusive.or.expr * * inclusive.or.expr 8 * : exclusive.or.expr * | inclusive.or.expr "|" exclusive.or.expr * * exclusive.or.expr 7 * : and.expr * | exclusive.or.expr "^" and.expr * * and.expr 6 * : equality.expr * | and.expr "&" equality.expr * * equality.expr 5 * : relational.expr * | equality.expr (EQ | NEQ) relational.expr * * relational.expr 4 * : shift.expr * | relational.expr (LE | GE | "<" | ">") shift.expr * | relational.expr INSTANCEOF class.type ("[" "]")* * * shift.expr 3 * : additive.expr * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr * * additive.expr 2 * : multiply.expr * | additive.expr ("+" | "-") multiply.expr * * multiply.expr 1 * : unary.expr * | multiply.expr ("*" | "/" | "%") unary.expr */ private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError { ASTree expr = parseUnaryExpr(tbl); for (;;) { int t = lex.lookAhead(); int p = getOpPrecedence(t); if (p == 0) return expr; else expr = binaryExpr2(tbl, expr, p); } } private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr) throws CompileError { int t = lex.lookAhead(); if (isBuiltinType(t)) { lex.get(); // primitive type int dim = parseArrayDimension(); return new InstanceOfExpr(t, dim, expr); } else { ASTList name = parseClassType(tbl); int dim = parseArrayDimension(); return new InstanceOfExpr(name, dim, expr); } } private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec) throws CompileError { int t = lex.get(); if (t == INSTANCEOF) return parseInstanceOf(tbl, expr); ASTree expr2 = parseUnaryExpr(tbl); for (;;) { int t2 = lex.lookAhead(); int p2 = getOpPrecedence(t2); if (p2 != 0 && prec > p2) expr2 = binaryExpr2(tbl, expr2, p2); else return BinExpr.makeBin(t, expr, expr2); } } // !"#$%&'( )*+,-./0 12345678 9:;<=>? private static final int[] binaryOpPrecedence = { 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0 }; private int getOpPrecedence(int c) { if ('!' <= c && c <= '?') return binaryOpPrecedence[c - '!']; else if (c == '^') return 7; else if (c == '|') return 8; else if (c == ANDAND) return 9; else if (c == OROR) return 10; else if (c == EQ || c == NEQ) return 5; else if (c == LE || c == GE || c == INSTANCEOF) return 4; else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT) return 3; else return 0; // not a binary operator } /* unary.expr : "++"|"--" unary.expr | "+"|"-" unary.expr | "!"|"~" unary.expr | cast.expr | postfix.expr unary.expr.not.plus.minus is a unary expression starting without "+", "-", "++", or "--". */ private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError { int t; switch (lex.lookAhead()) { case '+' : case '-' : case PLUSPLUS : case MINUSMINUS : case '!' : case '~' : t = lex.get(); if (t == '-') { int t2 = lex.lookAhead(); switch (t2) { case LongConstant : case IntConstant : case CharConstant : lex.get(); return new IntConst(-lex.getLong(), t2); case DoubleConstant : case FloatConstant : lex.get(); return new DoubleConst(-lex.getDouble(), t2); default : break; } } return Expr.make(t, parseUnaryExpr(tbl)); case '(' : return parseCast(tbl); default : return parsePostfix(tbl); } } /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr | "(" class.type ("[" "]")* ")" unary.expr2 unary.expr2 is a unary.expr begining with "(", NULL, StringL, Identifier, THIS, SUPER, or NEW.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -