📄 parser.java
字号:
throws ESException { Expr rexpr = null; int op = 0; int lex = 0; int prec = 0; while (true) { boolean doLookahead = false; boolean doPostfix = false; boolean isRightAssoc = false; int nextPrec = 0; int nextOp = 0; int nextLex = 0; switch (lexer.peek()) { case '=': if (op != 0 && lex != ',') throw error(L.l("illegal left hand side of assignment")); if (isBool) throw error(L.l("assignment used as boolean needs parentheses")); case Lexer.BIN_OP: // careful with and/or for unassigned local variables if (lexer.getOp() == Lexer.AND || lexer.getOp() == Lexer.OR) function.setVars(); // fall through case ',': case Lexer.BANDU_OP: case '?': nextLex = lexer.peek(); nextOp = lexer.getOp(); nextPrec = lexer.getPrecedence(); isRightAssoc = lexer.isRightAssoc(); doLookahead = true; break; default: return op != 0 ? lexpr.binaryOp(lex, op, rexpr) : lexpr; } if (nextPrec >= prevPrec) { return op != 0 ? lexpr.binaryOp(lex, op, rexpr) : lexpr; } else if (prec == 0) { } else if (nextPrec < prec) { rexpr = parseExprRec(rexpr, prec, isBool, isTop); continue; } else { lexpr = op != 0 ? lexpr.binaryOp(lex, op, rexpr) : lexpr; } prec = nextPrec; lex = nextLex; op = nextOp; if (doLookahead) lexer.next(); if (isRightAssoc) { /* XXX: is this the right thing to do? + 1 */ rexpr = parseExpression(prec + 1, isTop); } else if (op == '?') { function.setVars(); Expr mexpr = parseExpression(Parser.PREC_ASSIGN + 1); if (lexer.peek() != ':') throw expect("`:'"); lexer.next(); rexpr = parseExpression(Parser.PREC_ASSIGN + 1, isTop); lexpr = lexpr.conditional(mexpr, rexpr); op = 0; } else rexpr = parseTerm(isTop); } } /* * parseTerm * * term ::= BANDU_OP term * ::= UNARY_OP term * ::= IDENTIFIER termTail * ::= LITERAL termTail * ::= objLiteral termTail * ::= '(' expr ')' termTail */ private Expr parseTerm(boolean isTop) throws ESException { int op; switch (lexer.peek()) { case Lexer.BANDU_OP: case Lexer.UNARY_OP: lexer.next(); op = lexer.getOp(); return parseTerm(isTop).unaryOp(op); case Lexer.VOID: lexer.next(); return parseTerm(isTop).doVoid(); case Lexer.TYPEOF: lexer.next(); return parseTerm(isTop).typeof(); case Lexer.DELETE: lexer.next(); return parseTerm(isTop).delete(); case Lexer.POSTFIX: lexer.next(); op = lexer.getOp(); return parseTerm(isTop).prefix(op); case Lexer.LITERAL: case Lexer.REGEXP: case Lexer.IDENTIFIER: case Lexer.THIS: case Lexer.EVAL: case Lexer.NEW: case '(': case '{': case '[': case Lexer.HASH_REF: case Lexer.HASH_DEF: case Lexer.FUNCTION: return parseLhs(false, isTop); default: throw expect(L.l("expression")); } } /** * Parses the left-hand side of an expression * * @param hasNew true if this follows a new * @return the new expression */ private Expr parseLhs(boolean hasNew, boolean isTop) throws ESException { String name; int op; Expr expr = null; switch (lexer.next()) { case Lexer.NEW: return parseTermTail(parseLhs(true, isTop), hasNew, isTop); case Lexer.LITERAL: return parseTermTail(block.newLiteral(lexer.getLiteral()), hasNew, isTop); case Lexer.REGEXP: /* return parseTermTail(block.newRegexp(lexer.getLiteral(), lexer.getFlags()), hasNew, isTop); */ throw new UnsupportedOperationException(); case Lexer.IDENTIFIER: return parseTermTail(getVar(lexer.getId()), hasNew, isTop); case Lexer.THIS: return parseTermTail(block.newThis(), hasNew, isTop); case Lexer.EVAL: if (lexer.peek() != '(') throw expect("`('"); function.setArguments(); return parseTermTail(block.newVar(ESId.intern("eval")), hasNew, false); case '(': expr = parseExpression(PREC_MAX); if (lexer.next() != ')') throw expect("`)'"); return parseTermTail(expr, hasNew, isTop); case '{': expr = parseObjectLiteral(-1); if (lexer.next() != '}') throw expect("`}'"); return parseTermTail(expr, hasNew, isTop); case '[': expr = parseArrayLiteral(-1); if (lexer.next() != ']') throw expect("`]'"); return parseTermTail(expr, hasNew, isTop); case Lexer.FUNCTION: Function newFun = parseFunction(); //function.addFunction(newFun); function.addVariable(block, newFun.id, null); block.newVar(newFun.id).getVar().setType(Expr.TYPE_ES); expr = block.newVar(newFun.id); return parseTermTail(expr, hasNew, isTop); case Lexer.HASH_DEF: switch (lexer.peek()) { case '{': lexer.next(); expr = parseObjectLiteral(lexer.intValue); if (lexer.next() != '}') throw expect("`}'"); return parseTermTail(expr, hasNew, isTop); case '[': lexer.next(); expr = parseArrayLiteral(lexer.intValue); if (lexer.next() != ']') throw expect("`]'"); return parseTermTail(expr, hasNew, isTop); default: /* XXX: expr = parseLhs(hasNew, isTop); int var = code.newVar(); code.store(var); hashes.add(lexer.intValue, var); code.load(var); */ return expr; } /* case Lexer.HASH_REF: if (hashes.size() <= lexer.intValue || hashes.get(lexer.intValue) <= 0) throw error("bad sharp reference at " + getToken()); return parseTermTail(code.load(hashes.get(lexer.intValue)), hasNew, isTop); */ default: throw expect(L.l("term")); } } /* * parseTermTail * * termTail ::= * ::= '.' Id termTail * ::= '(' exprList ')' termTail * ::= '[' expr ']' termTail * ::= '++' termTail */ private Expr parseTermTail(Expr term, boolean hasNew, boolean isTop) throws ESException { int op; while (true) { switch (lexer.peek()) { case '.': lexer.next(); if (lexer.next() != Lexer.IDENTIFIER) throw expect(L.l("property name")); term = term.fieldReference(lexer.getId()); break; case '(': if (isTop && lexer.seenLineFeed()) return term; lexer.next(); int n = 0; CallExpr call; if (hasNew) call = term.startNew(); else call = term.startCall(); while (lexer.peek() != ')') { if (n != 0 && lexer.peek() != ',') throw expect("`,'"); else if (n != 0) lexer.next(); call.addCallParam(parseExpression(PREC_COMMA)); n++; } lexer.next(); if (hasNew) return call; else term = call; break; case '[': if (isTop && lexer.seenLineFeed()) return term; lexer.next(); term = term.fieldReference(parseExpression(PREC_MAX)); if (lexer.next() != ']') throw expect("`]'"); break; case Lexer.POSTFIX: if (hasNew) return term.startNew(); if (lexer.seenLineFeed()) return term; term = term.postfix(lexer.getOp()); lexer.next(); break; case '@': lexer.next(); term = term.cast(parseType()); break; default: if (hasNew) return term.startNew(); else return term; } } } private Expr parseObjectLiteral(int hash) throws ESException { Expr expr = block.newVar(ESId.intern("Object")); CallExpr call = expr.startCall(); /* if (hash >= 0) { if (hashes.size() <= hash) hashes.setLength(hash + 1); hashes.add(hash, var); } */ if (lexer.peek() == ',') { lexer.next(); return call; } while (lexer.peek() == Lexer.LITERAL || lexer.peek() == Lexer.IDENTIFIER) { ESId id; if (lexer.next() == Lexer.LITERAL) id = ESId.intern(lexer.literal.toString()); else id = lexer.getId(); if (lexer.next() != ':') throw expect("`:'"); call.addCallParam(block.newLiteral(id)); call.addCallParam(parseExpression(PREC_COMMA)); if (lexer.peek() != ',') break; lexer.next(); } return call; } private Expr parseArrayLiteral(int hash) throws ESException { Expr expr = block.newVar(ESId.intern("Array")); CallExpr call = expr.startCall(); boolean isFirst = true; while (lexer.peek() != ']') { if (lexer.peek() == ',') { lexer.next(); call.addCallParam(block.newLiteral(ESBase.esUndefined)); isFirst = false; continue; } Expr value = parseExpression(PREC_COMMA); if (isFirst && lexer.peek() == ']') return block.newArray(value); if (lexer.peek() != ',') { call.addCallParam(value); break; } lexer.next(); if (isFirst && lexer.peek() == ']') return block.newArray(value); isFirst = false; call.addCallParam(value); } return call; } /** * Gets a variable instance. */ private Expr getVar(ESId name) throws ESException { if (name == PACKAGES) return new PackageExpr(block); else if (name == JAVA) return new PackageExpr(block).fieldReference(JAVA); else if (name == CAUCHO) return new PackageExpr(block).fieldReference(COM).fieldReference(CAUCHO); else if (block.hasVar(name)) return block.newVar(name); else { for (int i = 0; i < importList.size(); i++) { String className = (String) importList.get(i); if (className.endsWith(".*")) className = className.substring(0, className.length() - 1) + name; try { Class cl = CauchoSystem.loadClass(className, false, getClassLoader()); return new JavaClassExpr(block, cl); } catch (Throwable e) { } } return block.newVar(name); } } /** * Returns the current filename being parsed. */ public String getFilename() { return lexer.getFilename(); } /** * Creates an error message with the given text. */ ESException error(String text) { return lexer.error(text); } /** * Returns the current token for an error message. */ private String getToken() { if (lexer.isEof()) return "end of file"; else return "`" + lexer.getToken() + "'"; } /** * Returns a parse exception when expecting a result. */ private ESException expect(String expect) { try { return lexer.error(L.l("expected {0} at {1}", expect, getToken())); } catch (Exception e) { e.printStackTrace(); return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -