?? parser.java
字號:
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 + -