📄 parser.java
字号:
default: parseStatement(); } } if (lexer.next() != '}') throw expect("`}'"); block = block.fillSwitch(exprs); } /** * while ::= WHILE '(' expr ')' stmt */ private void parseWhile(ESId id) throws ESException { lexer.next(); if (lexer.next() != '(') throw expect("`('"); Expr expr = parseBooleanExpression(PREC_MAX); if (expr instanceof LiteralExpr && ! ((LiteralExpr) expr).getLiteral().toBoolean()) throw error(L.l("while (false) is never executed.")); block = block.startWhile(id, expr); if (lexer.next() != ')') throw expect("`)'"); parseStatement(); block = block.endLoop(); } /** * for ::= FOR '(' expr ')' stmt */ private void parseFor(ESId id) throws ESException { lexer.next(); if (lexer.next() != '(') throw expect("`('"); boolean hasValue = false; Expr lhs = null; if (lexer.peek() == Lexer.VAR) { lhs = parseVar(true); } else if (lexer.peek() != ';') { lhs = parseExpression(PREC_MAX); } else if (lexer.peek() == Lexer.IN) throw expect(L.l("expression")); if (lexer.peek() == Lexer.IN) { parseForIn(id, lhs); return; } if (lhs != null) lhs.exprStatement(block.function); if (lexer.next() != ';') throw expect("`;'"); Expr test = null; if (lexer.peek() != ';') test = parseExpression(PREC_MAX); if (lexer.next() != ';') throw expect("`;'"); Expr incr = null; if (lexer.peek() != ')') { incr = parseExpression(PREC_MAX); incr.killValue(); } if (lexer.next() != ')') throw expect("`)'"); if (test instanceof LiteralExpr && ! ((LiteralExpr) test).getLiteral().toBoolean()) throw error(L.l("for (;false;) is never executed.")); block = block.startFor(id, test, incr); parseStatement(); block = block.endLoop(); } private void parseForIn(ESId id, Expr lhs) throws ESException { lexer.next(); String var = block.newIterator(id, parseExpression(PREC_MAX)); if (lexer.next() != ')') throw expect("`)'"); block = block.startWhile(id, block.hasNext(var)); block.addExpr(lhs.next(var, lhs)); parseStatement(); block = block.endLoop(); } /** * do ::= DO stmt WHILE '(' expr ')' */ private void parseDo(ESId id) throws ESException { lexer.next(); block = block.startDo(id); parseStatement(); if (lexer.next() != Lexer.WHILE) throw expect("`while'"); if (lexer.next() != '(') throw expect("`('"); block = block.endDo(parseBooleanExpression(PREC_MAX)); if (lexer.next() != ')') throw expect("`)'"); parseStatementEnd(); } /** * with ::= WITH '(' expr ')' stmt */ private void parseWith() throws ESException { lexer.next(); if (lexer.next() != '(') throw expect("`('"); block = block.startWith(parseExpression(PREC_MAX)); if (lexer.next() != ')') throw expect("`)'"); parseStatement(); block = block.endWith(); } /** * var ::= VAR id (= expr)? (, id (= expr)?)* */ private Expr parseVar(boolean keepValue) throws ESException { boolean isFirst = true; Expr retVar = null; do { lexer.next(); if (lexer.next() != Lexer.IDENTIFIER) throw expect(L.l("identifier")); ESId name = lexer.getId(); Expr type = null; if (lexer.peek() == ':') { lexer.next(); type = parseType(); } block.defVar(name, type); if (lexer.peek() == '=') { lexer.next(); Expr var = block.newVar(name, type); Expr value = parseExpression(Parser.PREC_ASSIGN + 1, true); block.evalExpr(); var.assign(value).exprStatement(block.function); } else if (keepValue) retVar = block.newVar(name, type); isFirst = false; } while (lexer.peek() == ','); return retVar; } /** * synchronized ::= SYNCHRONIZED '(' expr ')' stmt */ private void parseSynchronized() throws ESException { lexer.next(); if (lexer.next() != '(') throw expect("`('"); block = block.startSynchronized(parseExpression(PREC_MAX)); if (lexer.next() != ')') throw expect("`)'"); parseStatement(); block = block.endSynchronized(); } /** * try ::= TRY stmt (CATCH | FINALLY) */ private void parseTry() throws ESException { lexer.next(); block = block.startTry(); parseStatement(); block = block.endTry(); if (lexer.peek() == Lexer.CATCH) { parseCatch(); } else if (lexer.peek() == Lexer.FINALLY) parseFinally(); else throw error(L.l("expected `catch' or `finally' at {0}", getToken())); } /** * catch ::= CATCH '(' (expr lhs?)? ')' stmt */ private void parseCatch() throws ESException { block.function.disallowJavaLocal(); // XXX: don't forget catch w/o try boolean oldDead = block.isDead; boolean hasCatchall = false; while (lexer.peek() == Lexer.CATCH) { block.isDead = false; if (hasCatchall) throw error(L.l("catch () must be last catch clause")); lexer.next(); if (lexer.next() != '(') throw expect("`('"); String exceptionClass = ""; while (lexer.peek() == Lexer.IDENTIFIER) { lexer.next(); exceptionClass = exceptionClass + lexer.getText(); if (lexer.peek() != '.') break; lexer.next(); exceptionClass = exceptionClass + "."; if (lexer.peek() != Lexer.IDENTIFIER) throw expect(L.l("identifier")); } ESId name = null; if (lexer.peek() == Lexer.IDENTIFIER) { name = lexer.getId(); lexer.next(); } if (lexer.next() != ')') { if (exceptionClass.equals("")) throw expect(L.l("identifier")); else throw expect("`)'"); } if (name == null) { name = ESId.intern(exceptionClass); exceptionClass = "java.lang.Exception"; } Expr var = null; if (name != null) var = block.newVar(name); block = block.startCatch(exceptionClass, var); parseStatement(); if (! block.isDead) oldDead = false; block = block.endCatch(); } block.isDead = oldDead; // Don't forget to throw if (lexer.peek() == Lexer.FINALLY) parseFinally(); } /** * finally ::= FINALLY stmt */ private void parseFinally() throws ESException { boolean oldDead = block.isDead; block.isDead = false; lexer.next(); block = block.startFinally(); parseStatement(); block = block.endFinally(); block.isDead = oldDead; } static ESId BOGUS = ESId.intern("return "); /** * Parse a class */ private void parseClass() throws ESException { if (function.getParent() != null) throw error(L.l("`class' only allowed at top level")); lexer.next(); if (lexer.next() != Lexer.IDENTIFIER) throw expect("class name"); ESId id = lexer.getId(); ESId proto = parseExtends(); if (lexer.next() != '{') throw expect("`{'"); ParseClass oldClass = parseClass; Function oldGlobal = globalFunction; Function oldStatic = staticFunction; Function oldFunction = function; Block oldBlock = block; parseClass = oldClass.newClass(id); parseClass.setProto(proto); globalFunction = parseClass.newFunction(null, ESId.intern("global"), true); staticFunction = parseClass.newFunction(null, ESId.intern("__es_static"), true); parseClass.setGlobal(globalFunction); function = globalFunction; block = Block.create(this, function); parseBlock(true); block.finish(); block = Block.create(this, staticFunction); block.finish(); if (parseClass.getFunction(id) == null) { function = parseClass.newFunction(null, id, false); block = Block.create(this, function); block.finish(); } block = oldBlock; function = oldFunction; globalFunction = oldGlobal; staticFunction = oldStatic; parseClass = oldClass; if (lexer.next() != '}') throw expect("`}'"); } private ESId parseExtends() throws ESException { if (lexer.peek() != Lexer.EXTENDS) return null; lexer.next(); if (lexer.next() != Lexer.IDENTIFIER) throw expect(L.l("parent class name")); return lexer.getId(); } private void parseImport() throws ESException { CharBuffer path = new CharBuffer(); lexer.next(); while (true) { if (lexer.peek() == Lexer.BIN_OP && lexer.getOp() == '*') { lexer.next(); path.append('*'); importList.add(path.close()); return; } if (lexer.peek() != Lexer.IDENTIFIER) throw expect(L.l("identifier")); path.append(lexer.getText()); lexer.next(); if (lexer.peek() != '.') break; lexer.next(); path.append('.'); } String className = path.close(); String pathName = className.replace('.', '/') + ".js"; Path importPath = getScriptPath().lookup(pathName); if (importPath.exists()) { function.cl.addImport(pathName); return; } try { CauchoSystem.loadClass(className, false, getClassLoader()); importList.add(className); } catch (ClassNotFoundException e) { throw error(L.l("can't open import `{0}'", pathName)); } } /* private void parseStatic() throws ESException { if (function.rest != null || staticCode == null) throw error("illegal static statement"); lexer.next(); int oldVar = stmtVar; ParseFun oldFun = function; try { stmtVar = -1; function = staticFunction; parseStatement(staticCode); } finally { function = oldFun; stmtVar = oldVar; } } */ private Expr parseExpression(int prevPrec, boolean isTop) throws ESException { Expr result = parseExprRec(parseTerm(isTop), prevPrec, false, isTop); result.getType(); return result; } private Expr parseBooleanExpression(int prevPrec) throws ESException { Expr result = parseExprRec(parseTerm(false), prevPrec, true, false); result.getType(); return result; } private Expr parseExpression(int prevPrec) throws ESException { Expr result = parseExprRec(parseTerm(false), prevPrec, false, false); result.getType(); return result; } private Expr parseExpression() throws ESException { Expr result = parseExprRec(parseTerm(false), PREC_MAX, false, false); result.getType(); return result; } /* * parseExpression () * * Grammar: * expr ::= obj (op obj)* */ private Expr parseExprRec(Expr lexpr, int prevPrec, boolean isBool, boolean isTop)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -