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

📄 parser.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            if (matchToken(Token.LP)) {                decompiler.addToken(Token.LP);                /* Add the arguments to pn, if any are supplied. */                argumentList(pn);            }            /* XXX there's a check in the C source against             * "too many constructor arguments" - how many             * do we claim to support?             */            /* Experimental syntax:  allow an object literal to follow a new expression,             * which will mean a kind of anonymous class built with the JavaAdapter.             * the object literal will be passed as an additional argument to the constructor.             */            tt = peekToken();            if (tt == Token.LC) {                nf.addChildToBack(pn, primaryExpr());            }        } else {            pn = primaryExpr();        }        return memberExprTail(allowCallSyntax, pn);    }    private Node memberExprTail(boolean allowCallSyntax, Node pn)        throws IOException, ParserException    {      tailLoop:        for (;;) {            int tt = peekToken();            switch (tt) {              case Token.DOT:              case Token.DOTDOT:                {                    int memberTypeFlags;                    String s;                    consumeToken();                    decompiler.addToken(tt);                    memberTypeFlags = 0;                    if (tt == Token.DOTDOT) {                        mustHaveXML();                        memberTypeFlags = Node.DESCENDANTS_FLAG;                    }                    if (!compilerEnv.isXmlAvailable()) {                        mustMatchToken(Token.NAME, "msg.no.name.after.dot");                        s = ts.getString();                        decompiler.addName(s);                        pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);                        break;                    }                    tt = nextToken();                    switch (tt) {                      // handles: name, ns::name, ns::*, ns::[expr]                      case Token.NAME:                        s = ts.getString();                        decompiler.addName(s);                        pn = propertyName(pn, s, memberTypeFlags);                        break;                      // handles: *, *::name, *::*, *::[expr]                      case Token.MUL:                        decompiler.addName("*");                        pn = propertyName(pn, "*", memberTypeFlags);                        break;                      // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',                      //          '@::attr', '@::*', '@*', '@*::attr', '@*::*'                      case Token.XMLATTR:                        decompiler.addToken(Token.XMLATTR);                        pn = attributeAccess(pn, memberTypeFlags);                        break;                      default:                        reportError("msg.no.name.after.dot");                    }                }                break;              case Token.DOTQUERY:                consumeToken();                mustHaveXML();                decompiler.addToken(Token.DOTQUERY);                pn = nf.createDotQuery(pn, expr(false), ts.getLineno());                mustMatchToken(Token.RP, "msg.no.paren");                decompiler.addToken(Token.RP);                break;              case Token.LB:                consumeToken();                decompiler.addToken(Token.LB);                pn = nf.createElementGet(pn, null, expr(false), 0);                mustMatchToken(Token.RB, "msg.no.bracket.index");                decompiler.addToken(Token.RB);                break;              case Token.LP:                if (!allowCallSyntax) {                    break tailLoop;                }                consumeToken();                decompiler.addToken(Token.LP);                pn = nf.createCallOrNew(Token.CALL, pn);                /* Add the arguments to pn, if any are supplied. */                argumentList(pn);                break;              default:                break tailLoop;            }        }        return pn;    }    /*     * Xml attribute expression:     *   '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'     */    private Node attributeAccess(Node pn, int memberTypeFlags)        throws IOException    {        memberTypeFlags |= Node.ATTRIBUTE_FLAG;        int tt = nextToken();        switch (tt) {          // handles: @name, @ns::name, @ns::*, @ns::[expr]          case Token.NAME:            {                String s = ts.getString();                decompiler.addName(s);                pn = propertyName(pn, s, memberTypeFlags);            }            break;          // handles: @*, @*::name, @*::*, @*::[expr]          case Token.MUL:            decompiler.addName("*");            pn = propertyName(pn, "*", memberTypeFlags);            break;          // handles @[expr]          case Token.LB:            decompiler.addToken(Token.LB);            pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);            mustMatchToken(Token.RB, "msg.no.bracket.index");            decompiler.addToken(Token.RB);            break;          default:            reportError("msg.no.name.after.xmlAttr");            pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);            break;        }        return pn;    }    /**     * Check if :: follows name in which case it becomes qualified name     */    private Node propertyName(Node pn, String name, int memberTypeFlags)        throws IOException, ParserException    {        String namespace = null;        if (matchToken(Token.COLONCOLON)) {            decompiler.addToken(Token.COLONCOLON);            namespace = name;            int tt = nextToken();            switch (tt) {              // handles name::name              case Token.NAME:                name = ts.getString();                decompiler.addName(name);                break;              // handles name::*              case Token.MUL:                decompiler.addName("*");                name = "*";                break;              // handles name::[expr]              case Token.LB:                decompiler.addToken(Token.LB);                pn = nf.createElementGet(pn, namespace, expr(false),                                         memberTypeFlags);                mustMatchToken(Token.RB, "msg.no.bracket.index");                decompiler.addToken(Token.RB);                return pn;              default:                reportError("msg.no.name.after.coloncolon");                name = "?";            }        }        pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);        return pn;    }    private Node primaryExpr()        throws IOException, ParserException    {        Node pn;        int ttFlagged = nextFlaggedToken();        int tt = ttFlagged & CLEAR_TI_MASK;        switch(tt) {          case Token.FUNCTION:            return function(FunctionNode.FUNCTION_EXPRESSION);          case Token.LB: {            ObjArray elems = new ObjArray();            int skipCount = 0;            decompiler.addToken(Token.LB);            boolean after_lb_or_comma = true;            for (;;) {                tt = peekToken();                if (tt == Token.COMMA) {                    consumeToken();                    decompiler.addToken(Token.COMMA);                    if (!after_lb_or_comma) {                        after_lb_or_comma = true;                    } else {                        elems.add(null);                        ++skipCount;                    }                } else if (tt == Token.RB) {                    consumeToken();                    decompiler.addToken(Token.RB);                    break;                } else {                    if (!after_lb_or_comma) {                        reportError("msg.no.bracket.arg");                    }                    elems.add(assignExpr(false));                    after_lb_or_comma = false;                }            }            return nf.createArrayLiteral(elems, skipCount);          }          case Token.LC: {            ObjArray elems = new ObjArray();            decompiler.addToken(Token.LC);            if (!matchToken(Token.RC)) {                boolean first = true;            commaloop:                do {                    Object property;                    if (!first)                        decompiler.addToken(Token.COMMA);                    else                        first = false;                    tt = peekToken();                    switch(tt) {                      case Token.NAME:                      case Token.STRING:                        consumeToken();                        // map NAMEs to STRINGs in object literal context                        // but tell the decompiler the proper type                        String s = ts.getString();                        if (tt == Token.NAME) {                            decompiler.addName(s);                        } else {                            decompiler.addString(s);                        }                        property = ScriptRuntime.getIndexObject(s);                        break;                      case Token.NUMBER:                        consumeToken();                        double n = ts.getNumber();                        decompiler.addNumber(n);                        property = ScriptRuntime.getIndexObject(n);                        break;                      case Token.RC:                        // trailing comma is OK.                        break commaloop;                    default:                        reportError("msg.bad.prop");                        break commaloop;                    }                    mustMatchToken(Token.COLON, "msg.no.colon.prop");                    // OBJLIT is used as ':' in object literal for                    // decompilation to solve spacing ambiguity.                    decompiler.addToken(Token.OBJECTLIT);                    elems.add(property);                    elems.add(assignExpr(false));                } while (matchToken(Token.COMMA));                mustMatchToken(Token.RC, "msg.no.brace.prop");            }            decompiler.addToken(Token.RC);            return nf.createObjectLiteral(elems);          }          case Token.LP:            /* Brendan's IR-jsparse.c makes a new node tagged with             * TOK_LP here... I'm not sure I understand why.  Isn't             * the grouping already implicit in the structure of the             * parse tree?  also TOK_LP is already overloaded (I             * think) in the C IR as 'function call.'  */            decompiler.addToken(Token.LP);            pn = expr(false);            decompiler.addToken(Token.RP);            mustMatchToken(Token.RP, "msg.no.paren");            return pn;          case Token.XMLATTR:            mustHaveXML();            decompiler.addToken(Token.XMLATTR);            pn = attributeAccess(null, 0);            return pn;          case Token.NAME: {            String name = ts.getString();            if ((ttFlagged & TI_CHECK_LABEL) != 0) {                if (peekToken() == Token.COLON) {                    // Do not consume colon, it is used as unwind indicator                    // to return to statementHelper.                    // XXX Better way?                    return nf.createLabel(ts.getLineno());                }            }            decompiler.addName(name);            if (compilerEnv.isXmlAvailable()) {                pn = propertyName(null, name, 0);            } else {                pn = nf.createName(name);            }            return pn;          }          case Token.NUMBER: {            double n = ts.getNumber();            decompiler.addNumber(n);            return nf.createNumber(n);          }          case Token.STRING: {            String s = ts.getString();            decompiler.addString(s);            return nf.createString(s);          }          case Token.DIV:          case Token.ASSIGN_DIV: {            // Got / or /= which should be treated as regexp in fact            ts.readRegExp(tt);            String flags = ts.regExpFlags;            ts.regExpFlags = null;            String re = ts.getString();            decompiler.addRegexp(re, flags);            int index = currentScriptOrFn.addRegexp(re, flags);            return nf.createRegExp(index);          }          case Token.NULL:          case Token.THIS:          case Token.FALSE:          case Token.TRUE:            decompiler.addToken(tt);            return nf.createLeaf(tt);          case Token.RESERVED:            reportError("msg.reserved.id");            break;          case Token.ERROR:            /* the scanner or one of its subroutines reported the error. */            break;          case Token.EOF:            reportError("msg.unexpected.eof");            break;          default:            reportError("msg.syntax");            break;        }        return null;    // should never reach here    }}

⌨️ 快捷键说明

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