📄 parser.java
字号:
return pn; } private Node bitOrExpr(boolean inForInit) throws IOException, ParserException { Node pn = bitXorExpr(inForInit); while (matchToken(Token.BITOR)) { decompiler.addToken(Token.BITOR); pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit)); } return pn; } private Node bitXorExpr(boolean inForInit) throws IOException, ParserException { Node pn = bitAndExpr(inForInit); while (matchToken(Token.BITXOR)) { decompiler.addToken(Token.BITXOR); pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit)); } return pn; } private Node bitAndExpr(boolean inForInit) throws IOException, ParserException { Node pn = eqExpr(inForInit); while (matchToken(Token.BITAND)) { decompiler.addToken(Token.BITAND); pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit)); } return pn; } private Node eqExpr(boolean inForInit) throws IOException, ParserException { Node pn = relExpr(inForInit); for (;;) { int tt = peekToken(); switch (tt) { case Token.EQ: case Token.NE: case Token.SHEQ: case Token.SHNE: consumeToken(); int decompilerToken = tt; int parseToken = tt; if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) { // JavaScript 1.2 uses shallow equality for == and != . // In addition, convert === and !== for decompiler into // == and != since the decompiler is supposed to show // canonical source and in 1.2 ===, !== are allowed // only as an alias to ==, !=. switch (tt) { case Token.EQ: parseToken = Token.SHEQ; break; case Token.NE: parseToken = Token.SHNE; break; case Token.SHEQ: decompilerToken = Token.EQ; break; case Token.SHNE: decompilerToken = Token.NE; break; } } decompiler.addToken(decompilerToken); pn = nf.createBinary(parseToken, pn, relExpr(inForInit)); continue; } break; } return pn; } private Node relExpr(boolean inForInit) throws IOException, ParserException { Node pn = shiftExpr(); for (;;) { int tt = peekToken(); switch (tt) { case Token.IN: if (inForInit) break; // fall through case Token.INSTANCEOF: case Token.LE: case Token.LT: case Token.GE: case Token.GT: consumeToken(); decompiler.addToken(tt); pn = nf.createBinary(tt, pn, shiftExpr()); continue; } break; } return pn; } private Node shiftExpr() throws IOException, ParserException { Node pn = addExpr(); for (;;) { int tt = peekToken(); switch (tt) { case Token.LSH: case Token.URSH: case Token.RSH: consumeToken(); decompiler.addToken(tt); pn = nf.createBinary(tt, pn, addExpr()); continue; } break; } return pn; } private Node addExpr() throws IOException, ParserException { Node pn = mulExpr(); for (;;) { int tt = peekToken(); if (tt == Token.ADD || tt == Token.SUB) { consumeToken(); decompiler.addToken(tt); // flushNewLines pn = nf.createBinary(tt, pn, mulExpr()); continue; } break; } return pn; } private Node mulExpr() throws IOException, ParserException { Node pn = unaryExpr(); for (;;) { int tt = peekToken(); switch (tt) { case Token.MUL: case Token.DIV: case Token.MOD: consumeToken(); decompiler.addToken(tt); pn = nf.createBinary(tt, pn, unaryExpr()); continue; } break; } return pn; } private Node unaryExpr() throws IOException, ParserException { int tt; tt = peekToken(); switch(tt) { case Token.VOID: case Token.NOT: case Token.BITNOT: case Token.TYPEOF: consumeToken(); decompiler.addToken(tt); return nf.createUnary(tt, unaryExpr()); case Token.ADD: consumeToken(); // Convert to special POS token in decompiler and parse tree decompiler.addToken(Token.POS); return nf.createUnary(Token.POS, unaryExpr()); case Token.SUB: consumeToken(); // Convert to special NEG token in decompiler and parse tree decompiler.addToken(Token.NEG); return nf.createUnary(Token.NEG, unaryExpr()); case Token.INC: case Token.DEC: consumeToken(); decompiler.addToken(tt); return nf.createIncDec(tt, false, memberExpr(true)); case Token.DELPROP: consumeToken(); decompiler.addToken(Token.DELPROP); return nf.createUnary(Token.DELPROP, unaryExpr()); case Token.ERROR: consumeToken(); break; // XML stream encountered in expression. case Token.LT: if (compilerEnv.isXmlAvailable()) { consumeToken(); Node pn = xmlInitializer(); return memberExprTail(true, pn); } // Fall thru to the default handling of RELOP default: Node pn = memberExpr(true); // Don't look across a newline boundary for a postfix incop. tt = peekTokenOrEOL(); if (tt == Token.INC || tt == Token.DEC) { consumeToken(); decompiler.addToken(tt); return nf.createIncDec(tt, true, pn); } return pn; } return nf.createName("error"); // Only reached on error.Try to continue. } private Node xmlInitializer() throws IOException { int tt = ts.getFirstXMLToken(); if (tt != Token.XML && tt != Token.XMLEND) { reportError("msg.syntax"); return null; } /* Make a NEW node to append to. */ Node pnXML = nf.createLeaf(Token.NEW); String xml = ts.getString(); boolean fAnonymous = xml.trim().startsWith("<>"); Node pn = nf.createName(fAnonymous ? "XMLList" : "XML"); nf.addChildToBack(pnXML, pn); pn = null; Node expr; for (;;tt = ts.getNextXMLToken()) { switch (tt) { case Token.XML: xml = ts.getString(); decompiler.addName(xml); mustMatchToken(Token.LC, "msg.syntax"); decompiler.addToken(Token.LC); expr = (peekToken() == Token.RC) ? nf.createString("") : expr(false); mustMatchToken(Token.RC, "msg.syntax"); decompiler.addToken(Token.RC); if (pn == null) { pn = nf.createString(xml); } else { pn = nf.createBinary(Token.ADD, pn, nf.createString(xml)); } if (ts.isXMLAttribute()) { /* Need to put the result in double quotes */ expr = nf.createUnary(Token.ESCXMLATTR, expr); Node prepend = nf.createBinary(Token.ADD, nf.createString("\""), expr); expr = nf.createBinary(Token.ADD, prepend, nf.createString("\"")); } else { expr = nf.createUnary(Token.ESCXMLTEXT, expr); } pn = nf.createBinary(Token.ADD, pn, expr); break; case Token.XMLEND: xml = ts.getString(); decompiler.addName(xml); if (pn == null) { pn = nf.createString(xml); } else { pn = nf.createBinary(Token.ADD, pn, nf.createString(xml)); } nf.addChildToBack(pnXML, pn); return pnXML; default: reportError("msg.syntax"); return null; } } } private void argumentList(Node listNode) throws IOException, ParserException { boolean matched; matched = matchToken(Token.RP); if (!matched) { boolean first = true; do { if (!first) decompiler.addToken(Token.COMMA); first = false; if (peekToken() == Token.YIELD) { reportError("msg.yield.parenthesized"); } nf.addChildToBack(listNode, assignExpr(false)); } while (matchToken(Token.COMMA)); mustMatchToken(Token.RP, "msg.no.paren.arg"); } decompiler.addToken(Token.RP); } private Node memberExpr(boolean allowCallSyntax) throws IOException, ParserException { int tt; Node pn; /* Check for new expressions. */ tt = peekToken(); if (tt == Token.NEW) { /* Eat the NEW token. */ consumeToken(); decompiler.addToken(Token.NEW); /* Make a NEW node to append to. */ pn = nf.createCallOrNew(Token.NEW, memberExpr(false)); 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -