def __init__(self, module): self.default = None self._module = module self._tokens = {} self._tokensByGroup = [] # touple list (group, token) #self._closeTokens = [] # ordered list from tokens # lowest width first self._ordered = [] self._makeTokenStructs(getattr(module, "TOKENS")) if self.default is None: deft = Token("(?P<begin>)") deft.name = self.DEFAULT_TOKEN_NAME self.default = deft self._tokens[deft.name] = deft self._addToIndex(deft)
def _makeTokenStructs(self, tokens, parent=None): for name, value in tokens.iteritems(): if isinstance(value, Token): value.name = name value.group = parent value.lexer = self self._tokens[name] = value self._addToIndex(value) elif isinstance(value, str): tok = Token("(?P<begin>" + re.escape(value) + ")") tok.name = name tok.group = parent tok.lexer = self self._tokens[name] = value self._addToIndex(value) elif isinstance(value, TokenTable): self._makeTokenStructs(value.table, name) elif isinstance(value, dict): self._makeTokenStructs(value, name)
def decompile(cls, source, flags, properties): length = len(source) if (length == 0): return "" indent = properties.getInt(cls.INITIAL_INDENT_PROP, 0) if indent < 0: raise IllegalArgumentException() indentGap = properties.getInt(cls.INDENT_GAP_PROP, 4) if indentGap < 0: raise IllegalArgumentException() caseGap = properties.getInt(cls.CASE_GAP_PROP, 2) if caseGap < 0: raise IllegalArgumentException() result = StringBuffer() justFunctionBody = (0 != flags & Decompiler.cls.ONLY_BODY_FLAG) toSource = (0 != flags & Decompiler.cls.TO_SOURCE_FLAG) if cls.printSource: System.err.println("length:" + length) ## for-while i = 0 while i < length: tokenname = None if Token.printNames: tokenname = Token.name(source.charAt(i)) if tokenname is None: tokenname = "---" pad = "\t" if len(tokenname) > 7 else "\t\t" System.err.println(tokenname + pad + source.charAt(i) + "\t'" + ScriptRuntime.escapeString(source.substring(i, i + 1)) + "'") i += 1 System.err.println() braceNesting = 0 afterFirstEOL = False i = 0 topFunctionType = 0 if (source.charAt(i) == Token.SCRIPT): i += 1 topFunctionType = -1 else: topFunctionType = source.charAt(i + 1) if not toSource: result.cls.append('\n') ## for-while j = 0 while j < indent: result.cls.append(' ') j += 1 else: if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION): result.cls.append('(') while i < length: if source[i] in (Token.GET, Token.SET): result.cls.append("get " if (source.charAt(i) == Token.GET) else "set ") i += 1 i = cls.printSourceString(source, i + 1, False, result) i += 1 break elif source.charAt(i) in( Token.NAME, Token.REGEXP): i = cls.printSourceString(source, i + 1, False, result) continue elif source.charAt(i) == Token.STRING: i = cls.printSourceString(source, i + 1, True, result) continue elif source.charAt(i) == Token.NUMBER: i = cls.printSourceNumber(source, i + 1, result) continue elif source.charAt(i) == Token.TRUE: result.cls.append("true") break elif source.charAt(i) == Token.FALSE: result.cls.append("false") break elif source.charAt(i) == Token.NULL: result.cls.append("null") break elif source.charAt(i) == Token.THIS: result.cls.append("this") break elif source.charAt(i) == Token.FUNCTION: i += 1 result.cls.append("function ") break elif source.charAt(i) == cls.FUNCTION_END: break elif source.charAt(i) == Token.COMMA: result.cls.append(", ") break elif source.charAt(i) == Token.LC: braceNesting += 1 if (Token.EOL == cls.getNext(source, length, i)): indent += indentGap result.cls.append('{') break elif source.charAt(i) == Token.RC: braceNesting -= 1 if justFunctionBody and (braceNesting == 0): break result.cls.append('}') if cls.getNext(source, length, i) == cls.FUNCTION_END: indent -= indentGap break elif cls.getNext(source, length, i) == Token.ELSE: indent -= indentGap result.cls.append(' ') break break elif source.charAt(i) == Token.LP: result.cls.append('(') break elif source.charAt(i) == Token.RP: result.cls.append(')') if (Token.LC == cls.getNext(source, length, i)): result.cls.append(' ') break elif source.charAt(i) == Token.LB: result.cls.append('[') break elif source.charAt(i) == Token.RB: result.cls.append(']') break elif source.charAt(i) == Token.EOL: if toSource: break newLine = True if not afterFirstEOL: afterFirstEOL = True if justFunctionBody: result.setLength(0) indent -= indentGap newLine = False if newLine: result.cls.append('\n') if i + 1 < length: less = 0 nextToken = source.charAt(i + 1) if (nextToken == Token.CASE) or (nextToken == Token.DEFAULT): less = indentGap - caseGap else: if (nextToken == Token.RC): less = indentGap else: if (nextToken == Token.NAME): afterName = cls.getSourceStringEnd(source, i + 2) if (source.charAt(afterName) == Token.COLON): less = indentGap ## for-while while less < indent: result.cls.append(' ') less += 1 break elif source.charAt(i) == Token.DOT: result.cls.append('.') break elif source.charAt(i) == Token.NEW: result.cls.append("new ") break elif source.charAt(i) == Token.DELPROP: result.cls.append("delete ") break elif source.charAt(i) == Token.IF: result.cls.append("if ") break elif source.charAt(i) == Token.ELSE: result.cls.append("else ") break elif source.charAt(i) == Token.FOR: result.cls.append("for ") break elif source.charAt(i) == Token.IN: result.cls.append(" in ") break elif source.charAt(i) == Token.WITH: result.cls.append("with ") break elif source.charAt(i) == Token.WHILE: result.cls.append("while ") break elif source.charAt(i) == Token.DO: result.cls.append("do ") break elif source.charAt(i) == Token.TRY: result.cls.append("try ") break elif source.charAt(i) == Token.CATCH: result.cls.append("catch ") break elif source.charAt(i) == Token.FINALLY: result.cls.append("finally ") break elif source.charAt(i) == Token.THROW: result.cls.append("throw ") break elif source.charAt(i) == Token.SWITCH: result.cls.append("switch ") break elif source.charAt(i) == Token.BREAK: result.cls.append("break") if (Token.NAME == cls.getNext(source, length, i)): result.cls.append(' ') break elif source.charAt(i) == Token.CONTINUE: result.cls.append("continue") if (Token.NAME == cls.getNext(source, length, i)): result.cls.append(' ') break elif source.charAt(i) == Token.CASE: result.cls.append("case ") break elif source.charAt(i) == Token.DEFAULT: result.cls.append("default") break elif source.charAt(i) == Token.RETURN: result.cls.append("return") if (Token.SEMI != cls.getNext(source, length, i)): result.cls.append(' ') break elif source.charAt(i) == Token.VAR: result.cls.append("var ") break elif source.charAt(i) == Token.SEMI: result.cls.append(';') if (Token.EOL != cls.getNext(source, length, i)): result.cls.append(' ') break elif source.charAt(i) == Token.ASSIGN: result.cls.append(" = ") break elif source.charAt(i) == Token.ASSIGN_ADD: result.cls.append(" += ") break elif source.charAt(i) == Token.ASSIGN_SUB: result.cls.append(" -= ") break elif source.charAt(i) == Token.ASSIGN_MUL: result.cls.append(" *= ") break elif source.charAt(i) == Token.ASSIGN_DIV: result.cls.append(" /= ") break elif source.charAt(i) == Token.ASSIGN_MOD: result.cls.append(" %= ") break elif source.charAt(i) == Token.ASSIGN_BITOR: result.cls.append(" |= ") break elif source.charAt(i) == Token.ASSIGN_BITXOR: result.cls.append(" ^= ") break elif source.charAt(i) == Token.ASSIGN_BITAND: result.cls.append(" &= ") break elif source.charAt(i) == Token.ASSIGN_LSH: result.cls.append(" <<= ") break elif source.charAt(i) == Token.ASSIGN_RSH: result.cls.append(" >>= ") break elif source.charAt(i) == Token.ASSIGN_URSH: result.cls.append(" >>>= ") break elif source.charAt(i) == Token.HOOK: result.cls.append(" ? ") break elif source.charAt(i) == Token.OBJECTLIT: result.cls.append(':') break elif source.charAt(i) == Token.COLON: if (Token.EOL == cls.getNext(source, length, i)): result.cls.append(':') else: result.cls.append(" : ") break elif source.charAt(i) == Token.OR: result.cls.append(" || ") break elif source.charAt(i) == Token.AND: result.cls.append(" && ") break elif source.charAt(i) == Token.BITOR: result.cls.append(" | ") break elif source.charAt(i) == Token.BITXOR: result.cls.append(" ^ ") break elif source.charAt(i) == Token.BITAND: result.cls.append(" & ") break elif source.charAt(i) == Token.SHEQ: result.cls.append(" === ") break elif source.charAt(i) == Token.SHNE: result.cls.append(" !== ") break elif source.charAt(i) == Token.EQ: result.cls.append(" == ") break elif source.charAt(i) == Token.NE: result.cls.append(" != ") break elif source.charAt(i) == Token.LE: result.cls.append(" <= ") break elif source.charAt(i) == Token.LT: result.cls.append(" < ") break elif source.charAt(i) == Token.GE: result.cls.append(" >= ") break elif source.charAt(i) == Token.GT: result.cls.append(" > ") break elif source.charAt(i) == Token.INSTANCEOF: result.cls.append(" instanceof ") break elif source.charAt(i) == Token.LSH: result.cls.append(" << ") break elif source.charAt(i) == Token.RSH: result.cls.append(" >> ") break elif source.charAt(i) == Token.URSH: result.cls.append(" >>> ") break elif source.charAt(i) == Token.TYPEOF: result.cls.append("typeof ") break elif source.charAt(i) == Token.VOID: result.cls.append("void ") break elif source.charAt(i) == Token.CONST: result.cls.append("const ") break elif source.charAt(i) == Token.NOT: result.cls.append('!') break elif source.charAt(i) == Token.BITNOT: result.cls.append('~') break elif source.charAt(i) == Token.POS: result.cls.append('+') break elif source.charAt(i) == Token.NEG: result.cls.append('-') break elif source.charAt(i) == Token.INC: result.cls.append("++") break elif source.charAt(i) == Token.DEC: result.cls.append("--") break elif source.charAt(i) == Token.ADD: result.cls.append(" + ") break elif source.charAt(i) == Token.SUB: result.cls.append(" - ") break elif source.charAt(i) == Token.MUL: result.cls.append(" * ") break elif source.charAt(i) == Token.DIV: result.cls.append(" / ") break elif source.charAt(i) == Token.MOD: result.cls.append(" % ") break elif source.charAt(i) == Token.COLONCOLON: result.cls.append("::") break elif source.charAt(i) == Token.DOTDOT: result.cls.append("..") break elif source.charAt(i) == Token.DOTQUERY: result.cls.append(".(") break elif source.charAt(i) == Token.XMLATTR: result.cls.append('@') break else: raise RuntimeException("Token: " + Token.name(source.charAt(i))) i += 1 if not toSource: if not justFunctionBody: result.cls.append('\n') else: if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION): result.cls.append(')') return str(result)