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

📄 parser.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                switch (tt) {                  case Token.ERROR:                  case Token.EOF:                  case Token.RC:                    break bodyLoop;                  case Token.FUNCTION:                    consumeToken();                    n = function(FunctionNode.FUNCTION_STATEMENT);                    break;                  default:                    n = statement();                    break;                }                nf.addChildToBack(pn, n);            }        } catch (ParserException e) {            // Ignore it        } finally {            --nestingOfFunction;        }        return pn;    }    private Node function(int functionType)        throws IOException, ParserException    {        int syntheticType = functionType;        int baseLineno = ts.getLineno();  // line number where source starts        int functionSourceStart = decompiler.markFunctionStart(functionType);        String name;        Node memberExprNode = null;        if (matchToken(Token.NAME)) {            name = ts.getString();            decompiler.addName(name);            if (!matchToken(Token.LP)) {                if (compilerEnv.isAllowMemberExprAsFunctionName()) {                    // Extension to ECMA: if 'function <name>' does not follow                    // by '(', assume <name> starts memberExpr                    Node memberExprHead = nf.createName(name);                    name = "";                    memberExprNode = memberExprTail(false, memberExprHead);                }                mustMatchToken(Token.LP, "msg.no.paren.parms");            }        } else if (matchToken(Token.LP)) {            // Anonymous function            name = "";        } else {            name = "";            if (compilerEnv.isAllowMemberExprAsFunctionName()) {                // Note that memberExpr can not start with '(' like                // in function (1+2).toString(), because 'function (' already                // processed as anonymous function                memberExprNode = memberExpr(false);            }            mustMatchToken(Token.LP, "msg.no.paren.parms");        }        if (memberExprNode != null) {            syntheticType = FunctionNode.FUNCTION_EXPRESSION;        }        boolean nested = insideFunction();        FunctionNode fnNode = nf.createFunction(name);        if (nested || nestingOfWith > 0) {            // 1. Nested functions are not affected by the dynamic scope flag            // as dynamic scope is already a parent of their scope.            // 2. Functions defined under the with statement also immune to            // this setup, in which case dynamic scope is ignored in favor            // of with object.            fnNode.itsIgnoreDynamicScope = true;        }        int functionIndex = currentScriptOrFn.addFunction(fnNode);        int functionSourceEnd;        ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;        currentScriptOrFn = fnNode;        int savedNestingOfWith = nestingOfWith;        nestingOfWith = 0;        Hashtable savedLabelSet = labelSet;        labelSet = null;        ObjArray savedLoopSet = loopSet;        loopSet = null;        ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;        loopAndSwitchSet = null;        Node body;        String source;        try {            decompiler.addToken(Token.LP);            if (!matchToken(Token.RP)) {                boolean first = true;                do {                    if (!first)                        decompiler.addToken(Token.COMMA);                    first = false;                    mustMatchToken(Token.NAME, "msg.no.parm");                    String s = ts.getString();                    if (fnNode.hasParamOrVar(s)) {                        addWarning("msg.dup.parms", s);                    }                    fnNode.addParam(s);                    decompiler.addName(s);                } while (matchToken(Token.COMMA));                mustMatchToken(Token.RP, "msg.no.paren.after.parms");            }            decompiler.addToken(Token.RP);            mustMatchToken(Token.LC, "msg.no.brace.body");            decompiler.addEOL(Token.LC);            body = parseFunctionBody();            mustMatchToken(Token.RC, "msg.no.brace.after.body");            decompiler.addToken(Token.RC);            functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);            if (functionType != FunctionNode.FUNCTION_EXPRESSION) {                 if (compilerEnv.getLanguageVersion() >= Context.VERSION_1_2) {                    // function f() {} function g() {} is not allowed in 1.2                    // or later but for compatibility with old scripts                    // the check is done only if language is                    // explicitly set.                    //  XXX warning needed if version == VERSION_DEFAULT ?                    int tt = peekTokenOrEOL();                    if (tt == Token.FUNCTION) {                         reportError("msg.no.semi.stmt");                    }                 }                // Add EOL only if function is not part of expression                // since it gets SEMI + EOL from Statement in that case                decompiler.addToken(Token.EOL);            }        }        finally {            loopAndSwitchSet = savedLoopAndSwitchSet;            loopSet = savedLoopSet;            labelSet = savedLabelSet;            nestingOfWith = savedNestingOfWith;            currentScriptOrFn = savedScriptOrFn;        }        fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);        fnNode.setSourceName(sourceURI);        fnNode.setBaseLineno(baseLineno);        fnNode.setEndLineno(ts.getLineno());        Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);        if (memberExprNode != null) {            pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);            if (functionType != FunctionNode.FUNCTION_EXPRESSION) {                // XXX check JScript behavior: should it be createExprStatement?                pn = nf.createExprStatementNoReturn(pn, baseLineno);            }        }        return pn;    }    private Node statements()        throws IOException    {        Node pn = nf.createBlock(ts.getLineno());        int tt;        while((tt = peekToken()) > Token.EOF && tt != Token.RC) {            nf.addChildToBack(pn, statement());        }        return pn;    }    private Node condition()        throws IOException, ParserException    {        Node pn;        mustMatchToken(Token.LP, "msg.no.paren.cond");        decompiler.addToken(Token.LP);        pn = expr(false);        mustMatchToken(Token.RP, "msg.no.paren.after.cond");        decompiler.addToken(Token.RP);        // there's a check here in jsparse.c that corrects = to ==        return pn;    }    // match a NAME; return null if no match.    private Node matchJumpLabelName()        throws IOException, ParserException    {        Node label = null;        int tt = peekTokenOrEOL();        if (tt == Token.NAME) {            consumeToken();            String name = ts.getString();            decompiler.addName(name);            if (labelSet != null) {                label = (Node)labelSet.get(name);            }            if (label == null) {                reportError("msg.undef.label");            }        }        return label;    }    private Node statement()        throws IOException    {        try {            Node pn = statementHelper(null);            if (pn != null) {                return pn;            }        } catch (ParserException e) { }        // skip to end of statement        int lineno = ts.getLineno();        guessingStatementEnd: for (;;) {            int tt = peekTokenOrEOL();            consumeToken();            switch (tt) {              case Token.ERROR:              case Token.EOF:              case Token.EOL:              case Token.SEMI:                break guessingStatementEnd;            }        }        return nf.createExprStatement(nf.createName("error"), lineno);    }    /**     * Whether the "catch (e: e instanceof Exception) { ... }" syntax     * is implemented.     */    private Node statementHelper(Node statementLabel)        throws IOException, ParserException    {        Node pn = null;        int tt;        tt = peekToken();        switch(tt) {          case Token.IF: {            consumeToken();            decompiler.addToken(Token.IF);            int lineno = ts.getLineno();            Node cond = condition();            decompiler.addEOL(Token.LC);            Node ifTrue = statement();            Node ifFalse = null;            if (matchToken(Token.ELSE)) {                decompiler.addToken(Token.RC);                decompiler.addToken(Token.ELSE);                decompiler.addEOL(Token.LC);                ifFalse = statement();            }            decompiler.addEOL(Token.RC);            pn = nf.createIf(cond, ifTrue, ifFalse, lineno);            return pn;          }          case Token.SWITCH: {            consumeToken();            decompiler.addToken(Token.SWITCH);            int lineno = ts.getLineno();            mustMatchToken(Token.LP, "msg.no.paren.switch");            decompiler.addToken(Token.LP);            pn = enterSwitch(expr(false), lineno, statementLabel);            try {                mustMatchToken(Token.RP, "msg.no.paren.after.switch");                decompiler.addToken(Token.RP);                mustMatchToken(Token.LC, "msg.no.brace.switch");                decompiler.addEOL(Token.LC);                boolean hasDefault = false;                switchLoop: for (;;) {                    tt = nextToken();                    Node caseExpression;                    switch (tt) {                      case Token.RC:                        break switchLoop;                      case Token.CASE:                        decompiler.addToken(Token.CASE);                        caseExpression = expr(false);                        mustMatchToken(Token.COLON, "msg.no.colon.case");                        decompiler.addEOL(Token.COLON);                        break;                      case Token.DEFAULT:                        if (hasDefault) {                            reportError("msg.double.switch.default");                        }                        decompiler.addToken(Token.DEFAULT);                        hasDefault = true;                        caseExpression = null;                        mustMatchToken(Token.COLON, "msg.no.colon.case");                        decompiler.addEOL(Token.COLON);                        break;                      default:                        reportError("msg.bad.switch");                        break switchLoop;                    }                    Node block = nf.createLeaf(Token.BLOCK);                    while ((tt = peekToken()) != Token.RC                           && tt != Token.CASE                           && tt != Token.DEFAULT                           && tt != Token.EOF)                    {                        nf.addChildToBack(block, statement());                    }                    // caseExpression == null => add default lable                    nf.addSwitchCase(pn, caseExpression, block);                }                decompiler.addEOL(Token.RC);                nf.closeSwitch(pn);            } finally {                exitSwitch();            }            return pn;          }          case Token.WHILE: {            consumeToken();            decompiler.addToken(Token.WHILE);            Node loop = enterLoop(statementLabel);            try {                Node cond = condition();                decompiler.addEOL(Token.LC);                Node body = statement();                decompiler.addEOL(Token.RC);                pn = nf.createWhile(loop, cond, body);            } finally {                exitLoop();            }            return pn;          }          case Token.DO: {            consumeToken();            decompiler.addToken(Token.DO);            decompiler.addEOL(Token.LC);            Node loop = enterLoop(statementLabel);            try {                Node body = statement();                decompiler.addToken(Token.RC);                mustMatchToken(Token.WHILE, "msg.no.while.do");                decompiler.addToken(Token.WHILE);                Node cond = condition();                pn = nf.createDoWhile(loop, body, cond);            } finally {                exitLoop();            }            // Always auto-insert semicon to follow SpiderMonkey:            // It is required by EMAScript but is ignored by the rest of            // world, see bug 238945            matchToken(Token.SEMI);            decompiler.addEOL(Token.SEMI);            return pn;          }          case Token.FOR: {            consumeToken();            boolean isForEach = false;            decompiler.addToken(Token.FOR);            Node loop = enterLoop(statementLabel);            try {                Node init;  // Node init is also foo in 'foo in Object'                Node cond;  // Node cond is also object in 'foo in Object'                Node incr = null; // to kill warning                Node body;                // See if this is a for each () instead of just a for ()                if (matchToken(Token.NAME)) {                    decompiler.addName(ts.getString());                    if (ts.getString().equals("each")) {                        isForEach = true;                    } else {                        reportError("msg.no.paren.for");                    }                }                mustMatchToken(Token.LP, "msg.no.paren.for");                decompiler.addToken(Token.LP);

⌨️ 快捷键说明

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