⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            Node expr = expr(false);            pn = nf.createDefaultNamespace(expr, nsLine);            break;          case Token.NAME: {            int lineno = ts.getLineno();            String name = ts.getString();            setCheckForLabel();            pn = expr(false);            if (pn.getType() != Token.LABEL) {                pn = nf.createExprStatement(pn, lineno);            } else {                // Parsed the label: push back token should be                // colon that primaryExpr left untouched.                if (peekToken() != Token.COLON) Kit.codeBug();                consumeToken();                // depend on decompiling lookahead to guess that that                // last name was a label.                decompiler.addName(name);                decompiler.addEOL(Token.COLON);                if (labelSet == null) {                    labelSet = new Hashtable();                } else if (labelSet.containsKey(name)) {                    reportError("msg.dup.label");                }                boolean firstLabel;                if (statementLabel == null) {                    firstLabel = true;                    statementLabel = pn;                } else {                    // Discard multiple label nodes and use only                    // the first: it allows to simplify IRFactory                    firstLabel = false;                }                labelSet.put(name, statementLabel);                try {                    pn = statementHelper(statementLabel);                } finally {                    labelSet.remove(name);                }                if (firstLabel) {                    pn = nf.createLabeledStatement(statementLabel, pn);                }                return pn;            }            break;          }          default: {            int lineno = ts.getLineno();            pn = expr(false);            pn = nf.createExprStatement(pn, lineno);            break;          }        }        int ttFlagged = peekFlaggedToken();        switch (ttFlagged & CLEAR_TI_MASK) {          case Token.SEMI:            // Consume ';' as a part of expression            consumeToken();            break;          case Token.ERROR:          case Token.EOF:          case Token.RC:            // Autoinsert ;            break;          default:            if ((ttFlagged & TI_AFTER_EOL) == 0) {                // Report error if no EOL or autoinsert ; otherwise                reportError("msg.no.semi.stmt");            }            break;        }        decompiler.addEOL(Token.SEMI);        return pn;    }    /**     * Returns whether or not the bits in the mask have changed to all set.     * @param before bits before change     * @param after bits after change     * @param mask mask for bits     * @return true if all the bits in the mask are set in "after" but not      *              "before"     */    private static final boolean nowAllSet(int before, int after, int mask)    {        return ((before & mask) != mask) && ((after & mask) == mask);    }        private Node returnOrYield(int tt, boolean exprContext)        throws IOException, ParserException    {        if (!insideFunction()) {            reportError(tt == Token.RETURN ? "msg.bad.return"                                           : "msg.bad.yield");        }        consumeToken();        decompiler.addToken(tt);        int lineno = ts.getLineno();        Node e;        /* This is ugly, but we don't want to require a semicolon. */        switch (peekTokenOrEOL()) {          case Token.SEMI:          case Token.RC:          case Token.EOF:          case Token.EOL:          case Token.ERROR:          case Token.RB:          case Token.RP:          case Token.YIELD:            e = null;            break;          default:            e = expr(false);            break;        }        int before = endFlags;        Node ret;        if (tt == Token.RETURN) {            if (e == null ) {                endFlags |= Node.END_RETURNS;            } else {                endFlags |= Node.END_RETURNS_VALUE;                hasReturnValue = true;            }            ret = nf.createReturn(e, lineno);                        // see if we need a strict mode warning            if (nowAllSet(before, endFlags,                           Node.END_RETURNS|Node.END_RETURNS_VALUE))            {                addStrictWarning("msg.return.inconsistent", "");            }        } else {            endFlags |= Node.END_YIELDS;            ret = nf.createYield(e, lineno);            if (!exprContext)                ret = new Node(Token.EXPR_VOID, ret, lineno);        }        // see if we are mixing yields and value returns.        if (nowAllSet(before, endFlags,                       Node.END_YIELDS|Node.END_RETURNS_VALUE))        {            String name = ((FunctionNode)currentScriptOrFn).getFunctionName();            if (name.length() == 0)                addError("msg.anon.generator.returns", "");            else                addError("msg.generator.returns", name);        }        return ret;    }    /**     * Parse a 'var' or 'const' statement, or a 'var' init list in a for     * statement.     * @param inFor true if we are currently in the midst of the init     * clause of a for.     * @param inStatement true if called in a statement (as opposed to an     * expression) context     * @param declType A token value: either VAR, CONST, or LET depending on     * context.     * @return The parsed statement     * @throws IOException     * @throws ParserException     */    private Node variables(boolean inFor, int declType)        throws IOException, ParserException    {        Node result = nf.createVariables(declType, ts.getLineno());        boolean first = true;        for (;;) {            Node destructuring = null;            String s = null;            int tt = peekToken();            if (tt == Token.LB || tt == Token.LC) {                // Destructuring assignment, e.g., var [a,b] = ...                destructuring = primaryExpr();            } else {                // Simple variable name                mustMatchToken(Token.NAME, "msg.bad.var");                s = ts.getString();                    if (!first)                    decompiler.addToken(Token.COMMA);                first = false;                    decompiler.addName(s);                defineSymbol(declType, s);            }                Node init = null;            if (matchToken(Token.ASSIGN)) {                decompiler.addToken(Token.ASSIGN);                init = assignExpr(inFor);            }                if (destructuring != null) {                if (init == null) {                    if (!inFor)                        reportError("msg.destruct.assign.no.init");                    nf.addChildToBack(result, destructuring);                } else {                    nf.addChildToBack(result,                        nf.createDestructuringAssignment(declType,                            destructuring, init));                }            } else {                Node name = nf.createName(s);                if (init != null)                    nf.addChildToBack(name, init);                nf.addChildToBack(result, name);            }                if (!matchToken(Token.COMMA))                break;        }        return result;    }        private Node let(boolean isStatement)        throws IOException, ParserException    {        mustMatchToken(Token.LP, "msg.no.paren.after.let");        decompiler.addToken(Token.LP);        Node result = nf.createScopeNode(Token.LET, ts.getLineno());        pushScope(result);        try {              Node vars = variables(false, Token.LET);              nf.addChildToBack(result, vars);              mustMatchToken(Token.RP, "msg.no.paren.let");              decompiler.addToken(Token.RP);              if (isStatement && peekToken() == Token.LC) {                  // let statement                  consumeToken();                  decompiler.addEOL(Token.LC);                  nf.addChildToBack(result, statements(null));                  mustMatchToken(Token.RC, "msg.no.curly.let");                  decompiler.addToken(Token.RC);              } else {                  // let expression                  result.setType(Token.LETEXPR);                  nf.addChildToBack(result, expr(false));                  if (isStatement) {                      // let expression in statement context                      result = nf.createExprStatement(result, ts.getLineno());                  }              }        } finally {            popScope();        }        return result;    }        void defineSymbol(int declType, String name) {        Node.Scope definingScope = currentScope.getDefiningScope(name);        Node.Scope.Symbol symbol = definingScope != null                                   ? definingScope.getSymbol(name)                                  : null;        boolean error = false;        if (symbol != null && (symbol.declType == Token.CONST ||            declType == Token.CONST))        {            error = true;        } else {            switch (declType) {              case Token.LET:                if (symbol != null && definingScope == currentScope) {                    error = symbol.declType == Token.LET;                }                currentScope.putSymbol(name,                     new Node.Scope.Symbol(declType, name));                break;                              case Token.VAR:              case Token.CONST:              case Token.FUNCTION:                if (symbol != null) {                    if (symbol.declType == Token.VAR)                        addStrictWarning("msg.var.redecl", name);                    else if (symbol.declType == Token.LP) {                        addStrictWarning("msg.var.hides.arg", name);                    }                } else {                    currentScriptOrFn.putSymbol(name,                         new Node.Scope.Symbol(declType, name));                }                break;                              case Token.LP:                if (symbol != null) {                    // must be duplicate parameter. Second parameter hides the                     // first, so go ahead and add the second pararameter                    addWarning("msg.dup.parms", name);                }                currentScriptOrFn.putSymbol(name,                     new Node.Scope.Symbol(declType, name));                break;                              default:                throw Kit.codeBug();            }        }        if (error) {            addError(symbol.declType == Token.CONST ? "msg.const.redecl" :                     symbol.declType == Token.LET ? "msg.let.redecl" :                     symbol.declType == Token.VAR ? "msg.var.redecl" :                     symbol.declType == Token.FUNCTION ? "msg.fn.redecl" :                     "msg.parm.redecl", name);        }    }    private Node expr(boolean inForInit)        throws IOException, ParserException    {        Node pn = assignExpr(inForInit);        while (matchToken(Token.COMMA)) {            decompiler.addToken(Token.COMMA);            if (compilerEnv.isStrictMode() && !pn.hasSideEffects())                addStrictWarning("msg.no.side.effects", "");            if (peekToken() == Token.YIELD) {              reportError("msg.yield.parenthesized");            }            pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));        }        return pn;    }    private Node assignExpr(boolean inForInit)        throws IOException, ParserException    {        int tt = peekToken();        if (tt == Token.YIELD) {            consumeToken();            return returnOrYield(tt, true);        }        Node pn = condExpr(inForInit);        tt = peekToken();        if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {            consumeToken();            decompiler.addToken(tt);            pn = nf.createAssignment(tt, pn, assignExpr(inForInit));        }        return pn;    }    private Node condExpr(boolean inForInit)        throws IOException, ParserException    {        Node pn = orExpr(inForInit);        if (matchToken(Token.HOOK)) {            decompiler.addToken(Token.HOOK);            Node ifTrue = assignExpr(false);            mustMatchToken(Token.COLON, "msg.no.colon.cond");            decompiler.addToken(Token.COLON);            Node ifFalse = assignExpr(inForInit);            return nf.createCondExpr(pn, ifTrue, ifFalse);        }        return pn;    }    private Node orExpr(boolean inForInit)        throws IOException, ParserException    {        Node pn = andExpr(inForInit);        if (matchToken(Token.OR)) {            decompiler.addToken(Token.OR);            pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));        }        return pn;    }    private Node andExpr(boolean inForInit)        throws IOException, ParserException    {        Node pn = bitOrExpr(inForInit);        if (matchToken(Token.AND)) {            decompiler.addToken(Token.AND);            pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -