You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
More python2 -> python3 compatibility
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
*.pyc
|
||||
*~
|
||||
/.python-version
|
||||
/uncompyle6.egg-info
|
||||
build
|
||||
|
56
__pkginfo__.py
Normal file
56
__pkginfo__.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""uncompyle6 packaging information"""
|
||||
|
||||
# To the extent possible we make this file look more like a
|
||||
# configuration file rather than code like setup.py. I find putting
|
||||
# configuration stuff in the middle of a function call in setup.py,
|
||||
# which for example requires commas in between parameters, is a little
|
||||
# less elegant than having it here with reduced code, albeit there
|
||||
# still is some room for improvement.
|
||||
|
||||
# Things that change more often go here.
|
||||
copyright = """
|
||||
Copyright (C) 2015 Rocky Bernstein <rocky@gnu.org>.
|
||||
"""
|
||||
|
||||
# classifiers = ['Development Status :: 5 - Production/Stable',
|
||||
# 'Environment :: Console',
|
||||
# 'Intended Audience :: Developers',
|
||||
# 'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||
# 'Operating System :: OS Independent',
|
||||
# 'Programming Language :: Python',
|
||||
# 'Topic :: Software Development :: Debuggers',
|
||||
# 'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
# ]
|
||||
|
||||
# The rest in alphabetic order
|
||||
author = "Rocky Bernstein"
|
||||
author_email = "rocky@gnu.org"
|
||||
ftp_url = None
|
||||
# license = 'GPL'
|
||||
mailing_list = 'python-debugger@googlegroups.com'
|
||||
modname = 'uncompyle6'
|
||||
packages = ['uncompyle6', 'uncompyle6.opcodes']
|
||||
py_modules = None
|
||||
short_desc = 'Python byte-code to source-code converter'
|
||||
|
||||
import os
|
||||
import os.path, sys
|
||||
|
||||
|
||||
def get_srcdir():
|
||||
filename = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
|
||||
return os.path.realpath(filename)
|
||||
|
||||
# VERSION.py sets variable VERSION.
|
||||
ns = {}
|
||||
version = '2.0'
|
||||
web = 'https://github.com/rocky/uncompyle6/'
|
||||
|
||||
# tracebacks in zip files are funky and not debuggable
|
||||
zip_safe = False
|
||||
|
||||
|
||||
def read(*rnames):
|
||||
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
|
||||
|
||||
long_description = ( read("README.rst") + '\n' )
|
43
setup.py
43
setup.py
@@ -1,15 +1,38 @@
|
||||
#! python
|
||||
|
||||
"""Setup script for the 'uncompyle' distribution."""
|
||||
"""Setup script for the 'uncompyle6' distribution."""
|
||||
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
setup (name = "uncompyle6",
|
||||
version = "2.0",
|
||||
description = "Python byte-code to source-code converter",
|
||||
author = "Mysterie",
|
||||
author_email = "kajusska@gmail.com",
|
||||
url = "http://github.com/Mysterie/uncompyle2",
|
||||
packages=['uncompyle6', 'uncompyle6.opcode'],
|
||||
scripts=['scripts/uncompyle6']
|
||||
)
|
||||
# Get the package information used in setup().
|
||||
# from __pkginfo__ import \
|
||||
# author, author_email, classifiers, \
|
||||
# install_requires, license, long_description, \
|
||||
# modname, packages, py_modules, \
|
||||
# short_desc, version, web, zip_safe
|
||||
|
||||
from __pkginfo__ import \
|
||||
author, author_email, \
|
||||
long_description, \
|
||||
modname, packages, py_modules, \
|
||||
short_desc, version, web, zip_safe
|
||||
|
||||
__import__('pkg_resources')
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
author = author,
|
||||
author_email = author_email,
|
||||
# classifiers = classifiers,
|
||||
description = short_desc,
|
||||
# install_requires = install_requires,
|
||||
# license = license,
|
||||
long_description = long_description,
|
||||
py_modules = py_modules,
|
||||
name = modname,
|
||||
packages = packages,
|
||||
test_suite = 'nose.collector',
|
||||
url = web,
|
||||
setup_requires = ['nose>=1.0'],
|
||||
version = version,
|
||||
zip_safe = zip_safe)
|
||||
|
@@ -1,4 +1,6 @@
|
||||
#! python
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
"""
|
||||
compile_tests -- compile test patterns for the decompyle test suite
|
||||
"""
|
||||
@@ -20,8 +22,8 @@ for opt, val in opts:
|
||||
if args:
|
||||
raise 'This tool does not want any arguments'
|
||||
|
||||
print "Using files in dir %s" % src_dir
|
||||
print "Compiling into dir %s" % work_dir
|
||||
print("Using files in dir %s" % src_dir)
|
||||
print("Compiling into dir %s" % work_dir)
|
||||
|
||||
tests = {}
|
||||
|
||||
@@ -46,6 +48,7 @@ tests['2.3'] = tests['2.2']
|
||||
tests['2.5'] = tests['2.3']
|
||||
tests['2.6'] = tests['2.5']
|
||||
tests['2.7'] = ['mine'] + tests['2.6']
|
||||
tests['3.4'] = ['mine']
|
||||
total_tests = len(tests['2.7'])
|
||||
#tests['2.2'].sort(); print tests['2.2']
|
||||
|
||||
@@ -62,13 +65,13 @@ def compile_for_version(version):
|
||||
os.mkdir(target_dir)
|
||||
for file in tests[version]:
|
||||
compile(file, target_dir)
|
||||
|
||||
|
||||
try:
|
||||
version = '%i.%i' % sys.version_info[:2]
|
||||
except AttributeError:
|
||||
version = sys.version[:3]
|
||||
|
||||
print 'Compiling test files for Python', version,
|
||||
print '(%i/%i files)' % (len(tests[version]), total_tests)
|
||||
print('Compiling test files for Python', version)
|
||||
print('(%i/%i files)' % (len(tests[version]), total_tests))
|
||||
compile_for_version(version)
|
||||
print 'Done.'
|
||||
print('Done.')
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#! python
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
'''
|
||||
test_pythonlib -- uncompyle and verify Python libraries
|
||||
@@ -19,7 +20,7 @@ Step 2: Run the test:
|
||||
test_pythonlib --mylib --verify # decompile verify 'mylib'
|
||||
'''
|
||||
|
||||
from uncompyle2 import main, verify
|
||||
from uncompyle6 import main, verify
|
||||
import getopt, sys
|
||||
import os, time, shutil
|
||||
from fnmatch import fnmatch
|
||||
@@ -44,11 +45,11 @@ test_options = {
|
||||
#-----
|
||||
|
||||
def help():
|
||||
print 'Usage-Examples:'
|
||||
print 'test_pythonlib --all # decompile all tests (suite + libs)'
|
||||
print 'test_pythonlib --all --verify # decomyile all tests and verify results'
|
||||
print 'test_pythonlib --test # decompile only the testsuite'
|
||||
print 'test_pythonlib --2.2 --verify # decompile and verify python lib 2.2'
|
||||
print('Usage-Examples:')
|
||||
print('test_pythonlib --all # decompile all tests (suite + libs)')
|
||||
print('test_pythonlib --all --verify # decomyile all tests and verify results')
|
||||
print('test_pythonlib --test # decompile only the testsuite')
|
||||
print('test_pythonlib --2.2 --verify # decompile and verify python lib 2.2')
|
||||
|
||||
def do_tests(src_dir, patterns, target_dir, start_with=None, do_verify=0):
|
||||
def visitor(files, dirname, names):
|
||||
@@ -69,18 +70,18 @@ def do_tests(src_dir, patterns, target_dir, start_with=None, do_verify=0):
|
||||
try:
|
||||
start_with = files.index(start_with)
|
||||
files = files[start_with:]
|
||||
print '>>> starting with file', files[0]
|
||||
print('>>> starting with file', files[0])
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
print time.ctime()
|
||||
print 'Working directory: ', src_dir
|
||||
print(time.ctime())
|
||||
print('Working directory: ', src_dir)
|
||||
try:
|
||||
main(src_dir, target_dir, files, [], do_verify=do_verify)
|
||||
except (KeyboardInterrupt, OSError):
|
||||
print
|
||||
print
|
||||
exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
do_verify = 0
|
||||
test_dirs = []
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import uncompyle2
|
||||
from uncompyle2 import uncompyle, walker, verify, magics
|
||||
from uncompyle2.spark import GenericASTTraversal, GenericASTTraversalPruningException
|
||||
import uncompyle6
|
||||
from uncompyle6 import uncompyle, walker, verify, magics
|
||||
from uncompyle6.spark import GenericASTTraversal, GenericASTTraversalPruningException
|
||||
import sys, inspect, types, cStringIO
|
||||
|
||||
from collections import namedtuple
|
||||
@@ -137,7 +137,7 @@ def uncompyle_find(version, co, find_offset, out=sys.stdout, showasm=0, showast=
|
||||
# store final output stream for case of error
|
||||
__real_out = out or sys.stdout
|
||||
if version == 2.7:
|
||||
import uncompyle2.scanner27 as scan
|
||||
import uncompyle6.scanner27 as scan
|
||||
scanner = scan.Scanner27()
|
||||
elif version == 2.6:
|
||||
import scanner26 as scan
|
||||
|
@@ -1,3 +1,6 @@
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
'''
|
||||
Copyright (c) 1999 John Aycock
|
||||
Copyright (c) 2000 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
@@ -68,9 +71,9 @@ def _load_module(filename):
|
||||
try:
|
||||
version = float(magics.versions[magic])
|
||||
except KeyError:
|
||||
raise ImportError, "Unknown magic number %s in %s" % (ord(magic[0])+256*ord(magic[1]), filename)
|
||||
raise ImportError("Unknown magic number %s in %s" % (ord(magic[0])+256*ord(magic[1]), filename))
|
||||
if (version > 2.7) or (version < 2.5):
|
||||
raise ImportError, "This is a Python %s file! Only Python 2.5 to 2.7 files are supported." % version
|
||||
raise ImportError("This is a Python %s file! Only Python 2.5 to 2.7 files are supported." % version)
|
||||
#print version
|
||||
fp.read(4) # timestamp
|
||||
co = dis.marshalLoad(fp)
|
||||
@@ -105,7 +108,7 @@ def uncompyle(version, co, out=None, showasm=0, showast=0):
|
||||
walk = walker.Walker(out, scanner, showast=showast)
|
||||
try:
|
||||
ast = walk.build_ast(tokens, customize)
|
||||
except walker.ParserError, e : # parser failed, dump disassembly
|
||||
except walker.ParserError as e : # parser failed, dump disassembly
|
||||
print >>__real_out, e
|
||||
raise
|
||||
del tokens # save memory
|
||||
@@ -223,9 +226,9 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
if do_verify:
|
||||
try:
|
||||
verify.compare_code_with_srcfile(infile, outfile)
|
||||
if not outfile: print '\n# okay decompyling', infile, __memUsage()
|
||||
if not outfile: print('\n# okay decompyling', infile, __memUsage())
|
||||
okay_files += 1
|
||||
except verify.VerifyCmpError, e:
|
||||
except verify.VerifyCmpError as e:
|
||||
verify_failed_files += 1
|
||||
os.rename(outfile, outfile + '_unverified')
|
||||
if not outfile:
|
||||
@@ -233,7 +236,7 @@ def main(in_base, out_base, files, codes, outfile=None,
|
||||
print >>sys.stderr, e
|
||||
else:
|
||||
okay_files += 1
|
||||
if not outfile: print '\n# okay decompyling', infile, __memUsage()
|
||||
if not outfile: print('\n# okay decompyling', infile, __memUsage())
|
||||
if outfile:
|
||||
sys.stdout.write("decompiled %i files: %i okay, %i failed, %i verify failed\r" % (tot_files, okay_files, failed_files, verify_failed_files))
|
||||
sys.stdout.flush()
|
||||
|
@@ -1,16 +1,20 @@
|
||||
from __future__ import print_function
|
||||
import struct
|
||||
|
||||
import struct, sys
|
||||
|
||||
__all__ = ['magics', 'versions']
|
||||
|
||||
def __build_magic(magic):
|
||||
return struct.pack('Hcc', magic, '\r', '\n')
|
||||
if (sys.version_info > (3, 0)):
|
||||
return struct.pack('Hcc', magic, bytes('\r', 'utf-8'), bytes('\n', 'utf-8'))
|
||||
else:
|
||||
return struct.pack('Hcc', magic, '\r', '\n')
|
||||
|
||||
by_magic = {}
|
||||
by_version = {}
|
||||
|
||||
def __by_version(magics):
|
||||
for m, v in magics.items():
|
||||
for m, v in list(magics.items()):
|
||||
by_magic[m] = v
|
||||
by_version[v] = m
|
||||
return by_version
|
||||
@@ -77,6 +81,7 @@ def test():
|
||||
magic_20 = magics['2.0']
|
||||
current = imp.get_magic()
|
||||
current_version = struct.unpack('HBB', current)[0]
|
||||
from trepan.api import debug; debug()
|
||||
magic_current = by_magic[ current ]
|
||||
print(type(magic_20), len(magic_20), repr(magic_20))
|
||||
print()
|
||||
|
@@ -1,3 +1,5 @@
|
||||
from __future__ import print_function
|
||||
|
||||
'''
|
||||
Copyright (c) 1999 John Aycock
|
||||
Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
@@ -9,8 +11,13 @@
|
||||
__all__ = ['parse', 'AST', 'ParserError', 'Parser']
|
||||
|
||||
from spark import GenericASTBuilder
|
||||
import string, exceptions, sys
|
||||
from UserList import UserList
|
||||
import string, sys
|
||||
|
||||
if (sys.version_info > (3, 0)):
|
||||
intern = sys.intern
|
||||
from collections import UserList
|
||||
else:
|
||||
from UserList import UserList
|
||||
|
||||
from scanner import Token
|
||||
|
||||
@@ -44,9 +51,10 @@ class ParserError(Exception):
|
||||
def __str__(self):
|
||||
return "Syntax error at or near `%r' token at offset %s\n" % \
|
||||
(self.token, self.offset)
|
||||
|
||||
|
||||
|
||||
class Parser(GenericASTBuilder):
|
||||
|
||||
def __init__(self):
|
||||
GenericASTBuilder.__init__(self, AST, 'stmts')
|
||||
self.customized = {}
|
||||
@@ -57,7 +65,7 @@ class Parser(GenericASTBuilder):
|
||||
collector to collect this object.
|
||||
"""
|
||||
for dict in (self.rule2func, self.rules, self.rule2name):
|
||||
for i in dict.keys():
|
||||
for i in list(dict.keys()):
|
||||
dict[i] = None
|
||||
for i in dir(self):
|
||||
setattr(self, i, None)
|
||||
@@ -67,7 +75,7 @@ class Parser(GenericASTBuilder):
|
||||
|
||||
def typestring(self, token):
|
||||
return token.type
|
||||
|
||||
|
||||
def p_funcdef(self, args):
|
||||
'''
|
||||
stmt ::= funcdef
|
||||
@@ -92,26 +100,26 @@ class Parser(GenericASTBuilder):
|
||||
list_iter ::= lc_body
|
||||
|
||||
_come_from ::= COME_FROM
|
||||
_come_from ::=
|
||||
|
||||
_come_from ::=
|
||||
|
||||
list_for ::= expr _for designator list_iter JUMP_BACK
|
||||
list_if ::= expr jmp_false list_iter
|
||||
list_if_not ::= expr jmp_true list_iter
|
||||
list_if ::= expr jmp_false list_iter
|
||||
list_if_not ::= expr jmp_true list_iter
|
||||
|
||||
lc_body ::= expr LIST_APPEND
|
||||
'''
|
||||
|
||||
|
||||
def p_setcomp(self, args):
|
||||
'''
|
||||
expr ::= setcomp
|
||||
|
||||
|
||||
setcomp ::= LOAD_SETCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
||||
|
||||
|
||||
stmt ::= setcomp_func
|
||||
|
||||
|
||||
setcomp_func ::= BUILD_SET_0 LOAD_FAST FOR_ITER designator comp_iter
|
||||
JUMP_BACK RETURN_VALUE RETURN_LAST
|
||||
|
||||
|
||||
comp_iter ::= comp_if
|
||||
comp_iter ::= comp_ifnot
|
||||
comp_iter ::= comp_for
|
||||
@@ -131,11 +139,11 @@ class Parser(GenericASTBuilder):
|
||||
def p_genexpr(self, args):
|
||||
'''
|
||||
expr ::= genexpr
|
||||
|
||||
|
||||
genexpr ::= LOAD_GENEXPR MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
||||
|
||||
|
||||
stmt ::= genexpr_func
|
||||
|
||||
|
||||
genexpr_func ::= LOAD_FAST FOR_ITER designator comp_iter JUMP_BACK
|
||||
'''
|
||||
|
||||
@@ -145,7 +153,7 @@ class Parser(GenericASTBuilder):
|
||||
expr ::= dictcomp
|
||||
dictcomp ::= LOAD_DICTCOMP MAKE_FUNCTION_0 expr GET_ITER CALL_FUNCTION_1
|
||||
stmt ::= dictcomp_func
|
||||
|
||||
|
||||
dictcomp_func ::= BUILD_MAP LOAD_FAST FOR_ITER designator
|
||||
comp_iter JUMP_BACK RETURN_VALUE RETURN_LAST
|
||||
|
||||
@@ -177,7 +185,7 @@ class Parser(GenericASTBuilder):
|
||||
inplace_op ::= INPLACE_RSHIFT
|
||||
inplace_op ::= INPLACE_AND
|
||||
inplace_op ::= INPLACE_XOR
|
||||
inplace_op ::= INPLACE_OR
|
||||
inplace_op ::= INPLACE_OR
|
||||
'''
|
||||
|
||||
def p_assign(self, args):
|
||||
@@ -197,11 +205,11 @@ class Parser(GenericASTBuilder):
|
||||
stmt ::= print_items_stmt
|
||||
stmt ::= print_nl
|
||||
stmt ::= print_items_nl_stmt
|
||||
|
||||
|
||||
print_items_stmt ::= expr PRINT_ITEM print_items_opt
|
||||
print_items_nl_stmt ::= expr PRINT_ITEM print_items_opt PRINT_NEWLINE_CONT
|
||||
print_items_opt ::= print_items
|
||||
print_items_opt ::=
|
||||
print_items_opt ::=
|
||||
print_items ::= print_items print_item
|
||||
print_items ::= print_item
|
||||
print_item ::= expr PRINT_ITEM_CONT
|
||||
@@ -222,7 +230,7 @@ class Parser(GenericASTBuilder):
|
||||
'''
|
||||
|
||||
def p_import20(self, args):
|
||||
'''
|
||||
'''
|
||||
stmt ::= importstmt
|
||||
stmt ::= importfrom
|
||||
stmt ::= importstar
|
||||
@@ -234,20 +242,20 @@ class Parser(GenericASTBuilder):
|
||||
import_as ::= IMPORT_NAME load_attrs designator
|
||||
import_as ::= IMPORT_FROM designator
|
||||
|
||||
importstmt ::= LOAD_CONST LOAD_CONST import_as
|
||||
importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME IMPORT_STAR
|
||||
importstmt ::= LOAD_CONST LOAD_CONST import_as
|
||||
importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME IMPORT_STAR
|
||||
importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist2 POP_TOP
|
||||
importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT IMPORT_STAR
|
||||
importstar ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT IMPORT_STAR
|
||||
importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME_CONT importlist2 POP_TOP
|
||||
importmultiple ::= LOAD_CONST LOAD_CONST import_as imports_cont
|
||||
|
||||
|
||||
imports_cont ::= imports_cont import_cont
|
||||
imports_cont ::= import_cont
|
||||
import_cont ::= LOAD_CONST LOAD_CONST import_as_cont
|
||||
import_as_cont ::= IMPORT_NAME_CONT designator
|
||||
import_as_cont ::= IMPORT_NAME_CONT load_attrs designator
|
||||
import_as_cont ::= IMPORT_FROM designator
|
||||
|
||||
|
||||
load_attrs ::= LOAD_ATTR
|
||||
load_attrs ::= load_attrs LOAD_ATTR
|
||||
'''
|
||||
@@ -259,11 +267,11 @@ class Parser(GenericASTBuilder):
|
||||
sstmt ::= stmt
|
||||
sstmt ::= ifelsestmtr
|
||||
sstmt ::= return_stmt RETURN_LAST
|
||||
|
||||
|
||||
stmts_opt ::= stmts
|
||||
stmts_opt ::= passstmt
|
||||
passstmt ::=
|
||||
|
||||
passstmt ::=
|
||||
|
||||
_stmts ::= _stmts stmt
|
||||
_stmts ::= stmt
|
||||
|
||||
@@ -271,7 +279,7 @@ class Parser(GenericASTBuilder):
|
||||
c_stmts ::= _stmts lastc_stmt
|
||||
c_stmts ::= lastc_stmt
|
||||
c_stmts ::= continue_stmts
|
||||
|
||||
|
||||
lastc_stmt ::= iflaststmt
|
||||
lastc_stmt ::= whileelselaststmt
|
||||
lastc_stmt ::= forelselaststmt
|
||||
@@ -281,28 +289,28 @@ class Parser(GenericASTBuilder):
|
||||
|
||||
c_stmts_opt ::= c_stmts
|
||||
c_stmts_opt ::= passstmt
|
||||
|
||||
|
||||
l_stmts ::= _stmts
|
||||
l_stmts ::= return_stmts
|
||||
l_stmts ::= continue_stmts
|
||||
l_stmts ::= _stmts lastl_stmt
|
||||
l_stmts ::= lastl_stmt
|
||||
|
||||
|
||||
lastl_stmt ::= iflaststmtl
|
||||
lastl_stmt ::= ifelsestmtl
|
||||
lastl_stmt ::= forelselaststmtl
|
||||
lastl_stmt ::= tryelsestmtl
|
||||
|
||||
|
||||
l_stmts_opt ::= l_stmts
|
||||
l_stmts_opt ::= passstmt
|
||||
|
||||
|
||||
suite_stmts ::= _stmts
|
||||
suite_stmts ::= return_stmts
|
||||
suite_stmts ::= continue_stmts
|
||||
|
||||
|
||||
suite_stmts_opt ::= suite_stmts
|
||||
suite_stmts_opt ::= passstmt
|
||||
|
||||
|
||||
else_suite ::= suite_stmts
|
||||
else_suitel ::= l_stmts
|
||||
else_suitec ::= c_stmts
|
||||
@@ -324,7 +332,7 @@ class Parser(GenericASTBuilder):
|
||||
store_subscr ::= expr expr STORE_SUBSCR
|
||||
designator ::= unpack
|
||||
designator ::= unpack_list
|
||||
|
||||
|
||||
stmt ::= classdef
|
||||
stmt ::= call_stmt
|
||||
call_stmt ::= expr POP_TOP
|
||||
@@ -333,21 +341,21 @@ class Parser(GenericASTBuilder):
|
||||
return_stmt ::= ret_expr RETURN_VALUE
|
||||
return_stmts ::= return_stmt
|
||||
return_stmts ::= _stmts return_stmt
|
||||
|
||||
|
||||
return_if_stmts ::= return_if_stmt
|
||||
return_if_stmts ::= _stmts return_if_stmt
|
||||
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||
|
||||
stmt ::= break_stmt
|
||||
break_stmt ::= BREAK_LOOP
|
||||
|
||||
|
||||
stmt ::= continue_stmt
|
||||
continue_stmt ::= CONTINUE
|
||||
continue_stmt ::= CONTINUE_LOOP
|
||||
continue_stmts ::= _stmts lastl_stmt continue_stmt
|
||||
continue_stmts ::= lastl_stmt continue_stmt
|
||||
continue_stmts ::= continue_stmt
|
||||
|
||||
|
||||
stmt ::= raise_stmt0
|
||||
stmt ::= raise_stmt1
|
||||
stmt ::= raise_stmt2
|
||||
@@ -357,16 +365,16 @@ class Parser(GenericASTBuilder):
|
||||
raise_stmt1 ::= expr RAISE_VARARGS_1
|
||||
raise_stmt2 ::= expr expr RAISE_VARARGS_2
|
||||
raise_stmt3 ::= expr expr expr RAISE_VARARGS_3
|
||||
|
||||
|
||||
stmt ::= exec_stmt
|
||||
exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT
|
||||
exec_stmt ::= expr exprlist EXEC_STMT
|
||||
|
||||
|
||||
stmt ::= assert
|
||||
stmt ::= assert2
|
||||
stmt ::= ifstmt
|
||||
stmt ::= ifelsestmt
|
||||
|
||||
|
||||
stmt ::= whilestmt
|
||||
stmt ::= whilenotstmt
|
||||
stmt ::= while1stmt
|
||||
@@ -379,7 +387,7 @@ class Parser(GenericASTBuilder):
|
||||
stmt ::= tryfinallystmt
|
||||
stmt ::= withstmt
|
||||
stmt ::= withasstmt
|
||||
|
||||
|
||||
stmt ::= del_stmt
|
||||
del_stmt ::= DELETE_FAST
|
||||
del_stmt ::= DELETE_NAME
|
||||
@@ -391,12 +399,12 @@ class Parser(GenericASTBuilder):
|
||||
del_stmt ::= delete_subscr
|
||||
delete_subscr ::= expr expr DELETE_SUBSCR
|
||||
del_stmt ::= expr DELETE_ATTR
|
||||
|
||||
|
||||
kwarg ::= LOAD_CONST expr
|
||||
|
||||
|
||||
classdef ::= LOAD_CONST expr mkfunc
|
||||
CALL_FUNCTION_0 BUILD_CLASS designator
|
||||
|
||||
|
||||
stmt ::= classdefdeco
|
||||
classdefdeco ::= classdefdeco1 designator
|
||||
classdefdeco1 ::= expr classdefdeco1 CALL_FUNCTION_1
|
||||
@@ -411,11 +419,11 @@ class Parser(GenericASTBuilder):
|
||||
jmp_false ::= JUMP_IF_FALSE
|
||||
jmp_true ::= POP_JUMP_IF_TRUE
|
||||
jmp_true ::= JUMP_IF_TRUE
|
||||
|
||||
|
||||
assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1
|
||||
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
|
||||
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr RAISE_VARARGS_2
|
||||
|
||||
|
||||
assert_expr ::= expr
|
||||
assert_expr ::= assert_expr_or
|
||||
assert_expr ::= assert_expr_and
|
||||
@@ -423,17 +431,17 @@ class Parser(GenericASTBuilder):
|
||||
assert_expr_and ::= assert_expr jmp_false expr
|
||||
|
||||
ifstmt ::= testexpr _ifstmts_jump
|
||||
|
||||
|
||||
testexpr ::= testfalse
|
||||
testexpr ::= testtrue
|
||||
testfalse ::= expr jmp_false
|
||||
testtrue ::= expr jmp_true
|
||||
|
||||
|
||||
_ifstmts_jump ::= return_if_stmts
|
||||
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM
|
||||
|
||||
|
||||
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE
|
||||
|
||||
|
||||
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK
|
||||
|
||||
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM
|
||||
@@ -443,8 +451,8 @@ class Parser(GenericASTBuilder):
|
||||
ifelsestmtr ::= testexpr return_if_stmts return_stmts
|
||||
|
||||
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
||||
|
||||
|
||||
|
||||
|
||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||
try_middle COME_FROM
|
||||
|
||||
@@ -461,12 +469,12 @@ class Parser(GenericASTBuilder):
|
||||
END_FINALLY
|
||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
||||
END_FINALLY COME_FROM
|
||||
|
||||
|
||||
except_stmts ::= except_stmts except_stmt
|
||||
except_stmts ::= except_stmt
|
||||
|
||||
except_stmt ::= except_cond1 except_suite
|
||||
except_stmt ::= except_cond2 except_suite
|
||||
|
||||
except_stmt ::= except_cond1 except_suite
|
||||
except_stmt ::= except_cond2 except_suite
|
||||
except_stmt ::= except
|
||||
|
||||
except_suite ::= c_stmts_opt JUMP_FORWARD
|
||||
@@ -474,22 +482,22 @@ class Parser(GenericASTBuilder):
|
||||
except_suite ::= return_stmts
|
||||
|
||||
except_cond1 ::= DUP_TOP expr COMPARE_OP
|
||||
jmp_false POP_TOP POP_TOP POP_TOP
|
||||
jmp_false POP_TOP POP_TOP POP_TOP
|
||||
|
||||
except_cond2 ::= DUP_TOP expr COMPARE_OP
|
||||
jmp_false POP_TOP designator POP_TOP
|
||||
|
||||
|
||||
except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt JUMP_FORWARD
|
||||
except ::= POP_TOP POP_TOP POP_TOP c_stmts_opt jmp_abs
|
||||
except ::= POP_TOP POP_TOP POP_TOP return_stmts
|
||||
|
||||
|
||||
jmp_abs ::= JUMP_ABSOLUTE
|
||||
jmp_abs ::= JUMP_BACK
|
||||
|
||||
|
||||
tryfinallystmt ::= SETUP_FINALLY suite_stmts
|
||||
POP_BLOCK LOAD_CONST
|
||||
COME_FROM suite_stmts_opt END_FINALLY
|
||||
|
||||
|
||||
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt
|
||||
POP_BLOCK LOAD_CONST COME_FROM
|
||||
WITH_CLEANUP END_FINALLY
|
||||
@@ -527,7 +535,7 @@ class Parser(GenericASTBuilder):
|
||||
|
||||
for_block ::= l_stmts_opt JUMP_BACK
|
||||
for_block ::= return_stmts _come_from
|
||||
|
||||
|
||||
forstmt ::= SETUP_LOOP expr _for designator
|
||||
for_block POP_BLOCK COME_FROM
|
||||
|
||||
@@ -577,7 +585,7 @@ class Parser(GenericASTBuilder):
|
||||
expr ::= buildslice2
|
||||
expr ::= buildslice3
|
||||
expr ::= yield
|
||||
|
||||
|
||||
binary_expr ::= expr expr binary_op
|
||||
binary_op ::= BINARY_ADD
|
||||
binary_op ::= BINARY_MULTIPLY
|
||||
@@ -616,7 +624,7 @@ class Parser(GenericASTBuilder):
|
||||
slice3 ::= expr expr expr DUP_TOPX_3 SLICE+3
|
||||
buildslice3 ::= expr expr expr BUILD_SLICE_3
|
||||
buildslice2 ::= expr expr BUILD_SLICE_2
|
||||
|
||||
|
||||
yield ::= expr YIELD_VALUE
|
||||
|
||||
_mklambda ::= load_closure mklambda
|
||||
@@ -627,17 +635,17 @@ class Parser(GenericASTBuilder):
|
||||
and ::= expr jmp_false expr _come_from
|
||||
and ::= expr JUMP_IF_FALSE_OR_POP expr COME_FROM
|
||||
and2 ::= _jump jmp_false COME_FROM expr COME_FROM
|
||||
|
||||
|
||||
expr ::= conditional
|
||||
conditional ::= expr jmp_false expr JUMP_FORWARD expr COME_FROM
|
||||
conditional ::= expr jmp_false expr JUMP_ABSOLUTE expr
|
||||
expr ::= conditionalnot
|
||||
conditionalnot ::= expr jmp_true expr _jump expr COME_FROM
|
||||
|
||||
|
||||
ret_expr ::= expr
|
||||
ret_expr ::= ret_and
|
||||
ret_expr ::= ret_or
|
||||
|
||||
|
||||
ret_expr_or_cond ::= ret_expr
|
||||
ret_expr_or_cond ::= ret_cond
|
||||
ret_expr_or_cond ::= ret_cond_not
|
||||
@@ -649,9 +657,9 @@ class Parser(GenericASTBuilder):
|
||||
|
||||
stmt ::= return_lambda
|
||||
stmt ::= conditional_lambda
|
||||
|
||||
|
||||
return_lambda ::= ret_expr RETURN_VALUE LAMBDA_MARKER
|
||||
conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER
|
||||
conditional_lambda ::= expr jmp_false return_if_stmt return_stmt LAMBDA_MARKER
|
||||
|
||||
cmp ::= cmp_list
|
||||
cmp ::= compare
|
||||
@@ -704,7 +712,7 @@ class Parser(GenericASTBuilder):
|
||||
|
||||
def __ambiguity(self, children):
|
||||
# only for debugging! to be removed hG/2000-10-15
|
||||
print children
|
||||
print(children)
|
||||
return GenericASTBuilder.ambiguity(self, children)
|
||||
|
||||
def resolve(self, list):
|
||||
@@ -737,9 +745,9 @@ def parse(tokens, customize):
|
||||
# expr ::= expr {expr}^n CALL_FUNCTION_KW_n POP_TOP
|
||||
#
|
||||
global p
|
||||
for k, v in customize.items():
|
||||
for k, v in list(customize.items()):
|
||||
# avoid adding the same rule twice to this parser
|
||||
if p.customized.has_key(k):
|
||||
if k in p.customized:
|
||||
continue
|
||||
p.customized[k] = None
|
||||
|
||||
|
@@ -12,14 +12,14 @@ from array import array
|
||||
from operator import itemgetter
|
||||
from struct import *
|
||||
|
||||
from uncompyle2.opcode.opcode_25 import *
|
||||
from uncompyle6.opcodes.opcode_25 import *
|
||||
import disas as dis
|
||||
import scanner as scan
|
||||
|
||||
class Scanner25(scan.Scanner):
|
||||
def __init__(self):
|
||||
self.Token = scan.Scanner.__init__(self, 2.5)
|
||||
|
||||
|
||||
def disassemble(self, co, classname=None):
|
||||
'''
|
||||
Disassemble a code object, returning a list of 'Token'.
|
||||
@@ -38,7 +38,7 @@ class Scanner25(scan.Scanner):
|
||||
# linestarts contains bloc code adresse (addr,block)
|
||||
self.linestarts = list(dis.findlinestarts(co))
|
||||
self.prev = [0]
|
||||
|
||||
|
||||
# class and names
|
||||
if classname:
|
||||
classname = '_' + classname.lstrip('_') + '__'
|
||||
@@ -46,7 +46,7 @@ class Scanner25(scan.Scanner):
|
||||
if name.startswith(classname) and name[-2:] != '__':
|
||||
return name[len(classname) - 2:]
|
||||
return name
|
||||
|
||||
|
||||
free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
|
||||
names = [ unmangle(name) for name in co.co_names ]
|
||||
varnames = [ unmangle(name) for name in co.co_varnames ]
|
||||
@@ -82,13 +82,13 @@ class Scanner25(scan.Scanner):
|
||||
while j < codelen:
|
||||
self.lines.append(linetuple(prev_line_no, codelen))
|
||||
j+=1
|
||||
|
||||
|
||||
self.load_asserts = set()
|
||||
for i in self.op_range(0, codelen):
|
||||
if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL:
|
||||
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||
self.load_asserts.add(i+3)
|
||||
|
||||
|
||||
# self.lines contains (block,addrLastInstr)
|
||||
cf = self.find_jump_targets(self.code)
|
||||
# contains (code, [addrRefToCode])
|
||||
@@ -104,7 +104,7 @@ class Scanner25(scan.Scanner):
|
||||
replace[i] = 'PRINT_NEWLINE_CONT'
|
||||
last_stmt = i
|
||||
i = self.next_stmt[i]
|
||||
|
||||
|
||||
imports = self.all_instr(0, codelen, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR))
|
||||
if len(imports) > 1:
|
||||
last_import = imports[0]
|
||||
@@ -220,10 +220,10 @@ class Scanner25(scan.Scanner):
|
||||
'''
|
||||
opcode = self.code[i]
|
||||
opsize = self.op_size(opcode)
|
||||
|
||||
|
||||
if i+opsize >= len(self.code):
|
||||
return None
|
||||
|
||||
|
||||
if opcode == EXTENDED_ARG:
|
||||
raise NotImplementedError
|
||||
# del POP_TOP
|
||||
@@ -283,7 +283,7 @@ class Scanner25(scan.Scanner):
|
||||
target = self.get_target(target-3)
|
||||
self.restructJump(start, target)
|
||||
start += self.op_size(PJIF)
|
||||
# del DELETE_NAME x
|
||||
# del DELETE_NAME x
|
||||
start = end
|
||||
while end < len(self.code):
|
||||
end = self.first_instr(end, len(self.code), (DELETE_NAME,DELETE_FAST))
|
||||
@@ -297,7 +297,7 @@ class Scanner25(scan.Scanner):
|
||||
return toDel
|
||||
# change join(for..) struct
|
||||
if opcode == SETUP_LOOP:
|
||||
if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER:
|
||||
if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER:
|
||||
end = self.first_instr(i, len(self.code), RETURN_VALUE)
|
||||
end = self.first_instr(i, end, YIELD_VALUE)
|
||||
if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA and self.code[end+5] == POP_BLOCK:
|
||||
@@ -357,7 +357,7 @@ class Scanner25(scan.Scanner):
|
||||
i+=2
|
||||
i+=1
|
||||
return listExp
|
||||
|
||||
|
||||
def restructCode(self, listDel, listExp):
|
||||
'''
|
||||
restruct linestarts and jump destination
|
||||
@@ -389,7 +389,7 @@ class Scanner25(scan.Scanner):
|
||||
if listDel:
|
||||
for jmp in self.op_range(0, len(self.code)):
|
||||
op = self.code[jmp]
|
||||
if op in hasjrel+hasjabs:
|
||||
if op in hasjrel+hasjabs:
|
||||
offset = 0
|
||||
jmpTarget = self.get_target(jmp)
|
||||
for toDel in listDel:
|
||||
@@ -412,7 +412,7 @@ class Scanner25(scan.Scanner):
|
||||
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
|
||||
jmp += 3
|
||||
else: jmp += 1
|
||||
|
||||
|
||||
def restructBytecode(self):
|
||||
'''
|
||||
add/change/delete bytecode for suiting bytecode 2.7
|
||||
@@ -420,9 +420,9 @@ class Scanner25(scan.Scanner):
|
||||
# we can't use op_range for the moment
|
||||
# convert jump opcode to 2.7
|
||||
self.restructRelativeJump()
|
||||
|
||||
|
||||
listExp = self.getOpcodeToExp()
|
||||
# change code structure
|
||||
# change code structure
|
||||
if listExp:
|
||||
listExp = sorted(list(set(listExp)))
|
||||
self.restructCode([], listExp)
|
||||
@@ -439,7 +439,7 @@ class Scanner25(scan.Scanner):
|
||||
ret = self.getOpcodeToDel(i)
|
||||
if ret != None:
|
||||
listDel += ret
|
||||
|
||||
|
||||
# change code structure after deleting byte
|
||||
if listDel:
|
||||
listDel = sorted(list(set(listDel)))
|
||||
@@ -455,7 +455,7 @@ class Scanner25(scan.Scanner):
|
||||
else:
|
||||
self.code.pop(x-delta)
|
||||
delta += 1
|
||||
|
||||
|
||||
def restructRelativeJump(self):
|
||||
'''
|
||||
change relative JUMP_IF_FALSE/TRUE to absolut jump
|
||||
@@ -495,7 +495,7 @@ class Scanner25(scan.Scanner):
|
||||
raise NotImplementedError
|
||||
self.code[pos+2] = (target >> 8) & 0xFF
|
||||
self.code[pos+1] = target & 0xFF
|
||||
|
||||
|
||||
def build_stmt_indices(self):
|
||||
code = self.code
|
||||
start = 0;
|
||||
@@ -513,9 +513,9 @@ class Scanner25(scan.Scanner):
|
||||
}
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
|
||||
designator_ops = {
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
@@ -532,17 +532,17 @@ class Scanner25(scan.Scanner):
|
||||
match = False
|
||||
break
|
||||
i += self.op_size(code[i])
|
||||
|
||||
|
||||
if match:
|
||||
i = self.prev[i]
|
||||
stmts.add(i)
|
||||
pass_stmts.add(i)
|
||||
|
||||
|
||||
if pass_stmts:
|
||||
stmt_list = list(stmts)
|
||||
stmt_list.sort()
|
||||
else:
|
||||
stmt_list = prelim
|
||||
stmt_list = prelim
|
||||
last_stmt = -1
|
||||
self.next_stmt = []
|
||||
slist = self.next_stmt = []
|
||||
@@ -573,7 +573,7 @@ class Scanner25(scan.Scanner):
|
||||
slist += [s] * (s-i)
|
||||
i = s
|
||||
slist += [end] * (end-len(slist))
|
||||
|
||||
|
||||
def next_except_jump(self, start):
|
||||
'''
|
||||
Return the next jump that was generated by an except SomeException:
|
||||
@@ -602,7 +602,7 @@ class Scanner25(scan.Scanner):
|
||||
elif op in (SETUP_EXCEPT, SETUP_FINALLY):
|
||||
count_SETUP_ += 1
|
||||
#return self.lines[start].next
|
||||
|
||||
|
||||
def detect_structure(self, pos, op=None):
|
||||
'''
|
||||
Detect type of block structures and their boundaries to fix optimizied jumps
|
||||
@@ -635,7 +635,7 @@ class Scanner25(scan.Scanner):
|
||||
|
||||
if target != end:
|
||||
self.fixed_jumps[pos] = end
|
||||
|
||||
|
||||
(line_no, next_line_byte) = self.lines[pos]
|
||||
jump_back = self.last_instr(start, end, JA,
|
||||
next_line_byte, False)
|
||||
@@ -645,7 +645,7 @@ class Scanner25(scan.Scanner):
|
||||
jump_back = None
|
||||
if not jump_back: # loop suite ends in return. wtf right?
|
||||
jump_back = self.last_instr(start, end, RETURN_VALUE)
|
||||
if not jump_back:
|
||||
if not jump_back:
|
||||
return
|
||||
jump_back += 1
|
||||
if code[self.prev[next_line_byte]] not in (PJIF, PJIT):
|
||||
@@ -667,7 +667,7 @@ class Scanner25(scan.Scanner):
|
||||
elif target < pos:
|
||||
self.fixed_jumps[pos] = jump_back+4
|
||||
end = jump_back+4
|
||||
|
||||
|
||||
target = self.get_target(jump_back, JA)
|
||||
|
||||
if code[target] in (FOR_ITER, GET_ITER):
|
||||
@@ -677,7 +677,7 @@ class Scanner25(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
@@ -725,7 +725,7 @@ class Scanner25(scan.Scanner):
|
||||
self.structs.append({'type': 'except',
|
||||
'start': i,
|
||||
'end': jmp})
|
||||
i = jmp + 3
|
||||
i = jmp + 3
|
||||
|
||||
## Add the try-else block
|
||||
if end_else != start_else:
|
||||
@@ -754,7 +754,7 @@ class Scanner25(scan.Scanner):
|
||||
'start': start,
|
||||
'end': pre[target]})
|
||||
return
|
||||
|
||||
|
||||
# is this an if and
|
||||
if op == PJIF:
|
||||
match = self.rem_or(start, self.next_stmt[pos], PJIF, target)
|
||||
@@ -790,7 +790,7 @@ class Scanner25(scan.Scanner):
|
||||
self.fixed_jumps[pos] = fix or match[-1]
|
||||
return
|
||||
elif pos < rtarget and code[target] == ROT_TWO:
|
||||
self.fixed_jumps[pos] = target
|
||||
self.fixed_jumps[pos] = target
|
||||
return
|
||||
else:
|
||||
self.fixed_jumps[pos] = match[-1]
|
||||
@@ -800,7 +800,7 @@ class Scanner25(scan.Scanner):
|
||||
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||
return
|
||||
self.load_asserts.remove(pos+3)
|
||||
|
||||
|
||||
next = self.next_stmt[pos]
|
||||
if pre[next] == pos:
|
||||
pass
|
||||
@@ -816,7 +816,7 @@ class Scanner25(scan.Scanner):
|
||||
#don't add a struct for a while test, it's already taken care of
|
||||
if pos in self.ignore_if:
|
||||
return
|
||||
|
||||
|
||||
if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \
|
||||
and pre[rtarget] != pos and pre[pre[rtarget]] != pos \
|
||||
and not (code[rtarget] == JA and code[rtarget+3] == POP_BLOCK and code[pre[pre[rtarget]]] != JA):
|
||||
@@ -824,19 +824,19 @@ class Scanner25(scan.Scanner):
|
||||
#does the if jump just beyond a jump op, then this is probably an if statement
|
||||
if code[pre[rtarget]] in (JA, JF):
|
||||
if_end = self.get_target(pre[rtarget])
|
||||
|
||||
|
||||
#is this a loop not an if?
|
||||
if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP):
|
||||
if(if_end > start):
|
||||
return
|
||||
|
||||
|
||||
end = self.restrict_to_parent(if_end, parent)
|
||||
|
||||
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start,
|
||||
'end': pre[rtarget]})
|
||||
self.not_continue.add(pre[rtarget])
|
||||
|
||||
|
||||
if rtarget < end:
|
||||
self.structs.append({'type': 'if-else',
|
||||
'start': rtarget,
|
||||
@@ -867,7 +867,7 @@ class Scanner25(scan.Scanner):
|
||||
self.loops = [] ## All loop entry points
|
||||
self.fixed_jumps = {} ## Map fixed jumps to their real destination
|
||||
self.ignore_if = set()
|
||||
self.build_stmt_indices()
|
||||
self.build_stmt_indices()
|
||||
self.not_continue = set()
|
||||
self.return_end_ifs = set()
|
||||
|
||||
@@ -880,7 +880,7 @@ class Scanner25(scan.Scanner):
|
||||
|
||||
if self.op_hasArgument(op):
|
||||
label = self.fixed_jumps.get(i)
|
||||
oparg = self.get_argument(i)
|
||||
oparg = self.get_argument(i)
|
||||
if label is None:
|
||||
if op in hasjrel and op != FOR_ITER:
|
||||
label = i + 3 + oparg
|
||||
|
@@ -12,14 +12,14 @@ from array import array
|
||||
from operator import itemgetter
|
||||
from struct import *
|
||||
|
||||
from uncompyle2.opcode.opcode_26 import *
|
||||
from uncompyle6.opcodes.opcode_26 import *
|
||||
import disas as dis
|
||||
import scanner as scan
|
||||
|
||||
class Scanner26(scan.Scanner):
|
||||
def __init__(self):
|
||||
self.Token = scan.Scanner.__init__(self, 2.6)
|
||||
|
||||
|
||||
def disassemble(self, co, classname=None):
|
||||
'''
|
||||
Disassemble a code object, returning a list of 'Token'.
|
||||
@@ -27,7 +27,7 @@ class Scanner26(scan.Scanner):
|
||||
The main part of this procedure is modelled after
|
||||
dis.disassemble().
|
||||
'''
|
||||
|
||||
|
||||
rv = []
|
||||
customize = {}
|
||||
Token = self.Token # shortcut
|
||||
@@ -46,7 +46,7 @@ class Scanner26(scan.Scanner):
|
||||
if name.startswith(classname) and name[-2:] != '__':
|
||||
return name[len(classname) - 2:]
|
||||
return name
|
||||
|
||||
|
||||
free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
|
||||
names = [ unmangle(name) for name in co.co_names ]
|
||||
varnames = [ unmangle(name) for name in co.co_varnames ]
|
||||
@@ -60,7 +60,7 @@ class Scanner26(scan.Scanner):
|
||||
self.toChange = []
|
||||
self.restructBytecode()
|
||||
codelen = len(self.code)
|
||||
# mapping adresses of prev instru
|
||||
# mapping adresses of prev instru
|
||||
for i in self.op_range(0, codelen):
|
||||
op = self.code[i]
|
||||
self.prev.append(i)
|
||||
@@ -83,13 +83,13 @@ class Scanner26(scan.Scanner):
|
||||
self.lines.append(linetuple(prev_line_no, codelen))
|
||||
j+=1
|
||||
# self.lines contains (block,addrLastInstr)
|
||||
|
||||
|
||||
self.load_asserts = set()
|
||||
for i in self.op_range(0, codelen):
|
||||
if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL:
|
||||
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||
self.load_asserts.add(i+3)
|
||||
|
||||
|
||||
cf = self.find_jump_targets(self.code)
|
||||
# contains (code, [addrRefToCode])
|
||||
|
||||
@@ -105,7 +105,7 @@ class Scanner26(scan.Scanner):
|
||||
replace[i] = 'PRINT_NEWLINE_CONT'
|
||||
last_stmt = i
|
||||
i = self.next_stmt[i]
|
||||
|
||||
|
||||
imports = self.all_instr(0, codelen, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR))
|
||||
if len(imports) > 1:
|
||||
last_import = imports[0]
|
||||
@@ -248,10 +248,10 @@ class Scanner26(scan.Scanner):
|
||||
if destFor == i+opsize+4:
|
||||
setupLoop = self.last_instr(0, jmpabs1target, SETUP_LOOP)
|
||||
standarFor = self.last_instr(setupLoop, jmpabs1target, GET_ITER)
|
||||
if standarFor == None:
|
||||
if standarFor == None:
|
||||
self.restructJump(jmpabs1target, destFor+self.op_size(POP_BLOCK))
|
||||
toDel += [setupLoop, i+opsize+1, i+opsize+4]
|
||||
|
||||
|
||||
if len(toDel) > 0:
|
||||
return toDel
|
||||
return None
|
||||
@@ -288,7 +288,7 @@ class Scanner26(scan.Scanner):
|
||||
target = self.get_target(target-3)
|
||||
self.restructJump(start, target)
|
||||
start += self.op_size(PJIF)
|
||||
# del DELETE_NAME x
|
||||
# del DELETE_NAME x
|
||||
start = end
|
||||
while end < len(self.code):
|
||||
end = self.first_instr(end, len(self.code), (DELETE_NAME,DELETE_FAST))
|
||||
@@ -303,7 +303,7 @@ class Scanner26(scan.Scanner):
|
||||
# for / while struct
|
||||
if opcode == SETUP_LOOP:
|
||||
# change join(for..) struct
|
||||
if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER:
|
||||
if self.code[i+3] == LOAD_FAST and self.code[i+6] == FOR_ITER:
|
||||
end = self.first_instr(i, len(self.code), RETURN_VALUE)
|
||||
end = self.first_instr(i, end, YIELD_VALUE)
|
||||
if end and self.code[end+1] == POP_TOP and self.code[end+2] == JA and self.code[end+5] == POP_BLOCK:
|
||||
@@ -385,7 +385,7 @@ class Scanner26(scan.Scanner):
|
||||
if listDel:
|
||||
for jmp in self.op_range(0, len(self.code)):
|
||||
op = self.code[jmp]
|
||||
if op in hasjrel+hasjabs:
|
||||
if op in hasjrel+hasjabs:
|
||||
offset = 0
|
||||
jmpTarget = self.get_target(jmp)
|
||||
for toDel in listDel:
|
||||
@@ -416,9 +416,9 @@ class Scanner26(scan.Scanner):
|
||||
# we can't use op_range for the moment
|
||||
# convert jump opcode to 2.7
|
||||
self.restructRelativeJump()
|
||||
|
||||
|
||||
listExp = self.getOpcodeToExp()
|
||||
# change code structure
|
||||
# change code structure
|
||||
if listExp:
|
||||
listExp = sorted(list(set(listExp)))
|
||||
self.restructCode([], listExp)
|
||||
@@ -435,7 +435,7 @@ class Scanner26(scan.Scanner):
|
||||
ret = self.getOpcodeToDel(i)
|
||||
if ret != None:
|
||||
listDel += ret
|
||||
|
||||
|
||||
# change code structure after deleting byte
|
||||
if listDel:
|
||||
listDel = sorted(list(set(listDel)))
|
||||
@@ -479,7 +479,7 @@ class Scanner26(scan.Scanner):
|
||||
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
|
||||
i += 3
|
||||
else: i += 1
|
||||
|
||||
|
||||
def restructJump(self, pos, newTarget):
|
||||
if not (self.code[pos] in hasjabs+hasjrel):
|
||||
raise 'Can t change this argument. Opcode is not a jump'
|
||||
@@ -491,7 +491,7 @@ class Scanner26(scan.Scanner):
|
||||
raise NotImplementedError
|
||||
self.code[pos+2] = (target >> 8) & 0xFF
|
||||
self.code[pos+1] = target & 0xFF
|
||||
|
||||
|
||||
def build_stmt_indices(self):
|
||||
code = self.code
|
||||
start = 0;
|
||||
@@ -509,9 +509,9 @@ class Scanner26(scan.Scanner):
|
||||
}
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
|
||||
designator_ops = {
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
@@ -528,17 +528,17 @@ class Scanner26(scan.Scanner):
|
||||
match = False
|
||||
break
|
||||
i += self.op_size(code[i])
|
||||
|
||||
|
||||
if match:
|
||||
i = self.prev[i]
|
||||
stmts.add(i)
|
||||
pass_stmts.add(i)
|
||||
|
||||
|
||||
if pass_stmts:
|
||||
stmt_list = list(stmts)
|
||||
stmt_list.sort()
|
||||
else:
|
||||
stmt_list = prelim
|
||||
stmt_list = prelim
|
||||
last_stmt = -1
|
||||
self.next_stmt = []
|
||||
slist = self.next_stmt = []
|
||||
@@ -634,7 +634,7 @@ class Scanner26(scan.Scanner):
|
||||
|
||||
if target != end:
|
||||
self.fixed_jumps[pos] = end
|
||||
|
||||
|
||||
(line_no, next_line_byte) = self.lines[pos]
|
||||
jump_back = self.last_instr(start, end, JA,
|
||||
next_line_byte, False)
|
||||
@@ -644,7 +644,7 @@ class Scanner26(scan.Scanner):
|
||||
jump_back = None
|
||||
if not jump_back: # loop suite ends in return. wtf right?
|
||||
jump_back = self.last_instr(start, end, RETURN_VALUE)
|
||||
if not jump_back:
|
||||
if not jump_back:
|
||||
return
|
||||
jump_back += 1
|
||||
if code[self.prev[next_line_byte]] not in (PJIF, PJIT):
|
||||
@@ -666,7 +666,7 @@ class Scanner26(scan.Scanner):
|
||||
elif target < pos:
|
||||
self.fixed_jumps[pos] = jump_back+4
|
||||
end = jump_back+4
|
||||
|
||||
|
||||
target = self.get_target(jump_back, JA)
|
||||
|
||||
if code[target] in (FOR_ITER, GET_ITER):
|
||||
@@ -676,7 +676,7 @@ class Scanner26(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
@@ -725,7 +725,7 @@ class Scanner26(scan.Scanner):
|
||||
self.structs.append({'type': 'except',
|
||||
'start': i,
|
||||
'end': jmp})
|
||||
i = jmp + 3
|
||||
i = jmp + 3
|
||||
|
||||
## Add the try-else block
|
||||
if end_else != start_else:
|
||||
@@ -754,7 +754,7 @@ class Scanner26(scan.Scanner):
|
||||
'start': start,
|
||||
'end': pre[target]})
|
||||
return
|
||||
|
||||
|
||||
# is this an if and
|
||||
if op == PJIF:
|
||||
match = self.rem_or(start, self.next_stmt[pos], PJIF, target)
|
||||
@@ -790,7 +790,7 @@ class Scanner26(scan.Scanner):
|
||||
self.fixed_jumps[pos] = fix or match[-1]
|
||||
return
|
||||
elif pos < rtarget and code[target] == ROT_TWO:
|
||||
self.fixed_jumps[pos] = target
|
||||
self.fixed_jumps[pos] = target
|
||||
return
|
||||
else:
|
||||
self.fixed_jumps[pos] = match[-1]
|
||||
@@ -800,7 +800,7 @@ class Scanner26(scan.Scanner):
|
||||
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||
return
|
||||
self.load_asserts.remove(pos+3)
|
||||
|
||||
|
||||
next = self.next_stmt[pos]
|
||||
if pre[next] == pos:
|
||||
pass
|
||||
@@ -816,7 +816,7 @@ class Scanner26(scan.Scanner):
|
||||
#don't add a struct for a while test, it's already taken care of
|
||||
if pos in self.ignore_if:
|
||||
return
|
||||
|
||||
|
||||
if code[pre[rtarget]] == JA and pre[rtarget] in self.stmts \
|
||||
and pre[rtarget] != pos and pre[pre[rtarget]] != pos \
|
||||
and not (code[rtarget] == JA and code[rtarget+3] == POP_BLOCK and code[pre[pre[rtarget]]] != JA):
|
||||
@@ -824,19 +824,19 @@ class Scanner26(scan.Scanner):
|
||||
#does the if jump just beyond a jump op, then this is probably an if statement
|
||||
if code[pre[rtarget]] in (JA, JF):
|
||||
if_end = self.get_target(pre[rtarget])
|
||||
|
||||
|
||||
#is this a loop not an if?
|
||||
if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP):
|
||||
if(if_end > start):
|
||||
return
|
||||
|
||||
|
||||
end = self.restrict_to_parent(if_end, parent)
|
||||
|
||||
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start,
|
||||
'end': pre[rtarget]})
|
||||
self.not_continue.add(pre[rtarget])
|
||||
|
||||
|
||||
if rtarget < end:
|
||||
self.structs.append({'type': 'if-else',
|
||||
'start': rtarget,
|
||||
@@ -867,7 +867,7 @@ class Scanner26(scan.Scanner):
|
||||
self.loops = [] ## All loop entry points
|
||||
self.fixed_jumps = {} ## Map fixed jumps to their real destination
|
||||
self.ignore_if = set()
|
||||
self.build_stmt_indices()
|
||||
self.build_stmt_indices()
|
||||
self.not_continue = set()
|
||||
self.return_end_ifs = set()
|
||||
|
||||
@@ -880,7 +880,7 @@ class Scanner26(scan.Scanner):
|
||||
|
||||
if self.op_hasArgument(op):
|
||||
label = self.fixed_jumps.get(i)
|
||||
oparg = self.get_argument(i)
|
||||
oparg = self.get_argument(i)
|
||||
if label is None:
|
||||
if op in hasjrel and op != FOR_ITER:
|
||||
label = i + 3 + oparg
|
||||
@@ -894,4 +894,3 @@ class Scanner26(scan.Scanner):
|
||||
label = self.fixed_jumps[i]
|
||||
targets[label] = targets.get(label, []) + [i]
|
||||
return targets
|
||||
|
||||
|
@@ -11,14 +11,14 @@ from collections import namedtuple
|
||||
from array import array
|
||||
from operator import itemgetter
|
||||
|
||||
from uncompyle2.opcode.opcode_27 import *
|
||||
from uncompyle6.opcodes.opcode_27 import *
|
||||
import disas as dis
|
||||
import scanner as scan
|
||||
|
||||
class Scanner27(scan.Scanner):
|
||||
def __init__(self):
|
||||
self.Token = scan.Scanner.__init__(self, 2.7) # check
|
||||
|
||||
|
||||
def disassemble(self, co, classname=None):
|
||||
'''
|
||||
Disassemble a code object, returning a list of 'Token'.
|
||||
@@ -33,7 +33,7 @@ class Scanner27(scan.Scanner):
|
||||
if self.code[i] in (RETURN_VALUE, END_FINALLY):
|
||||
n = i + 1
|
||||
self.code = array('B', co.co_code[:n])
|
||||
|
||||
|
||||
self.prev = [0]
|
||||
# mapping adresses of instru & arg
|
||||
for i in self.op_range(0, n):
|
||||
@@ -42,7 +42,7 @@ class Scanner27(scan.Scanner):
|
||||
if op >= HAVE_ARGUMENT:
|
||||
self.prev.append(i)
|
||||
self.prev.append(i)
|
||||
|
||||
|
||||
self.lines = []
|
||||
linetuple = namedtuple('linetuple', ['l_no', 'next'])
|
||||
j = 0
|
||||
@@ -66,7 +66,7 @@ class Scanner27(scan.Scanner):
|
||||
if name.startswith(classname) and name[-2:] != '__':
|
||||
return name[len(classname) - 2:]
|
||||
return name
|
||||
|
||||
|
||||
free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
|
||||
names = [ unmangle(name) for name in co.co_names ]
|
||||
varnames = [ unmangle(name) for name in co.co_varnames ]
|
||||
@@ -80,7 +80,7 @@ class Scanner27(scan.Scanner):
|
||||
if self.code[i] == PJIT and self.code[i+3] == LOAD_GLOBAL:
|
||||
if names[self.get_argument(i+3)] == 'AssertionError':
|
||||
self.load_asserts.add(i+3)
|
||||
|
||||
|
||||
cf = self.find_jump_targets(self.code)
|
||||
# contains (code, [addrRefToCode])
|
||||
last_stmt = self.next_stmt[0]
|
||||
@@ -95,7 +95,7 @@ class Scanner27(scan.Scanner):
|
||||
replace[i] = 'PRINT_NEWLINE_CONT'
|
||||
last_stmt = i
|
||||
i = self.next_stmt[i]
|
||||
|
||||
|
||||
imports = self.all_instr(0, n, (IMPORT_NAME, IMPORT_FROM, IMPORT_STAR))
|
||||
if len(imports) > 1:
|
||||
last_import = imports[0]
|
||||
@@ -104,7 +104,7 @@ class Scanner27(scan.Scanner):
|
||||
if self.code[last_import] == IMPORT_NAME == self.code[i]:
|
||||
replace[i] = 'IMPORT_NAME_CONT'
|
||||
last_import = i
|
||||
|
||||
|
||||
extended_arg = 0
|
||||
for offset in self.op_range(0, n):
|
||||
if offset in cf:
|
||||
@@ -113,7 +113,7 @@ class Scanner27(scan.Scanner):
|
||||
rv.append(Token('COME_FROM', None, repr(j),
|
||||
offset="%s_%d" % (offset, k)))
|
||||
k += 1
|
||||
|
||||
|
||||
op = self.code[offset]
|
||||
op_name = opname[op]
|
||||
oparg = None; pattr = None
|
||||
@@ -193,7 +193,7 @@ class Scanner27(scan.Scanner):
|
||||
rv.append(Token(op_name, oparg, pattr, offset, linestart = offset in linestartoffsets))
|
||||
else:
|
||||
rv.append(Token(replace[offset], oparg, pattr, offset, linestart = offset in linestartoffsets))
|
||||
|
||||
|
||||
if self.showasm:
|
||||
out = self.out # shortcut
|
||||
for t in rv:
|
||||
@@ -206,12 +206,12 @@ class Scanner27(scan.Scanner):
|
||||
return 1
|
||||
else:
|
||||
return 3
|
||||
|
||||
|
||||
def build_stmt_indices(self):
|
||||
code = self.code
|
||||
start = 0;
|
||||
end = len(code)
|
||||
|
||||
|
||||
stmt_opcodes = {
|
||||
SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP,
|
||||
SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT, SETUP_WITH,
|
||||
@@ -226,9 +226,9 @@ class Scanner27(scan.Scanner):
|
||||
}
|
||||
|
||||
stmt_opcode_seqs = [(PJIF, JF), (PJIF, JA), (PJIT, JF), (PJIT, JA)]
|
||||
|
||||
|
||||
designator_ops = {
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
|
||||
STORE_SLICE_0, STORE_SLICE_1, STORE_SLICE_2, STORE_SLICE_3,
|
||||
STORE_SUBSCR, UNPACK_SEQUENCE, JA
|
||||
}
|
||||
@@ -245,12 +245,12 @@ class Scanner27(scan.Scanner):
|
||||
match = False
|
||||
break
|
||||
i += self.op_size(code[i])
|
||||
|
||||
|
||||
if match:
|
||||
i = self.prev[i]
|
||||
stmts.add(i)
|
||||
pass_stmts.add(i)
|
||||
|
||||
|
||||
if pass_stmts:
|
||||
stmt_list = list(stmts)
|
||||
stmt_list.sort()
|
||||
@@ -286,7 +286,7 @@ class Scanner27(scan.Scanner):
|
||||
slist += [s] * (s-i)
|
||||
i = s
|
||||
slist += [end] * (end-len(slist))
|
||||
|
||||
|
||||
def remove_mid_line_ifs(self, ifs):
|
||||
filtered = []
|
||||
for i in ifs:
|
||||
@@ -309,7 +309,7 @@ class Scanner27(scan.Scanner):
|
||||
self.ignore_if.add(except_match)
|
||||
self.not_continue.add(jmp)
|
||||
return jmp
|
||||
|
||||
|
||||
count_END_FINALLY = 0
|
||||
count_SETUP_ = 0
|
||||
for i in self.op_range(start, len(self.code)):
|
||||
@@ -367,7 +367,7 @@ class Scanner27(scan.Scanner):
|
||||
jump_back = None
|
||||
if not jump_back: # loop suite ends in return. wtf right?
|
||||
jump_back = self.last_instr(start, end, RETURN_VALUE) + 1
|
||||
if not jump_back:
|
||||
if not jump_back:
|
||||
return
|
||||
if code[self.prev[next_line_byte]] not in (PJIF, PJIT):
|
||||
loop_type = 'for'
|
||||
@@ -388,7 +388,7 @@ class Scanner27(scan.Scanner):
|
||||
self.fixed_jumps[pos] = jump_back+4
|
||||
end = jump_back+4
|
||||
target = self.get_target(jump_back, JA)
|
||||
|
||||
|
||||
if code[target] in (FOR_ITER, GET_ITER):
|
||||
loop_type = 'for'
|
||||
else:
|
||||
@@ -396,7 +396,7 @@ class Scanner27(scan.Scanner):
|
||||
test = self.prev[next_line_byte]
|
||||
if test == pos:
|
||||
loop_type = 'while 1'
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
elif self.code[test] in hasjabs+hasjrel:
|
||||
self.ignore_if.add(test)
|
||||
test_target = self.get_target(test)
|
||||
if test_target > (jump_back+3):
|
||||
@@ -441,7 +441,7 @@ class Scanner27(scan.Scanner):
|
||||
self.structs.append({'type': 'except',
|
||||
'start': i,
|
||||
'end': jmp})
|
||||
i = jmp + 3
|
||||
i = jmp + 3
|
||||
|
||||
## Add the try-else block
|
||||
if end_else != start_else:
|
||||
@@ -452,14 +452,14 @@ class Scanner27(scan.Scanner):
|
||||
self.fixed_jumps[i] = r_end_else
|
||||
else:
|
||||
self.fixed_jumps[i] = i+1
|
||||
|
||||
|
||||
|
||||
elif op in (PJIF, PJIT):
|
||||
start = pos+3
|
||||
start = pos+3
|
||||
target = self.get_target(pos, op)
|
||||
rtarget = self.restrict_to_parent(target, parent)
|
||||
pre = self.prev
|
||||
|
||||
|
||||
if target != rtarget and parent['type'] == 'and/or':
|
||||
self.fixed_jumps[pos] = rtarget
|
||||
return
|
||||
@@ -472,7 +472,7 @@ class Scanner27(scan.Scanner):
|
||||
'start': start,
|
||||
'end': pre[target]})
|
||||
return
|
||||
|
||||
|
||||
# is this an if and
|
||||
if op == PJIF:
|
||||
match = self.rem_or(start, self.next_stmt[pos], PJIF, target)
|
||||
@@ -516,7 +516,7 @@ class Scanner27(scan.Scanner):
|
||||
if code[pre[rtarget]] == RAISE_VARARGS:
|
||||
return
|
||||
self.load_asserts.remove(pos+3)
|
||||
|
||||
|
||||
next = self.next_stmt[pos]
|
||||
if pre[next] == pos:
|
||||
pass
|
||||
@@ -533,7 +533,7 @@ class Scanner27(scan.Scanner):
|
||||
elif code[next_target] in (JA, JF) and self.get_target(next_target) == self.get_target(target):
|
||||
self.fixed_jumps[pos] = pre[next]
|
||||
return
|
||||
|
||||
|
||||
#don't add a struct for a while test, it's already taken care of
|
||||
if pos in self.ignore_if:
|
||||
return
|
||||
@@ -552,19 +552,19 @@ class Scanner27(scan.Scanner):
|
||||
#does the if jump just beyond a jump op, then this is probably an if statement
|
||||
if code[pre[rtarget]] in (JA, JF):
|
||||
if_end = self.get_target(pre[rtarget])
|
||||
|
||||
|
||||
#is this a loop not an if?
|
||||
if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP):
|
||||
if(if_end > start):
|
||||
return
|
||||
|
||||
|
||||
end = self.restrict_to_parent(if_end, parent)
|
||||
|
||||
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start,
|
||||
'end': pre[rtarget]})
|
||||
self.not_continue.add(pre[rtarget])
|
||||
|
||||
|
||||
if rtarget < end:
|
||||
self.structs.append({'type': 'if-else',
|
||||
'start': rtarget,
|
||||
@@ -617,7 +617,7 @@ class Scanner27(scan.Scanner):
|
||||
if op in (JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP):
|
||||
if (oparg > i):
|
||||
label = oparg
|
||||
|
||||
|
||||
if label is not None and label != -1:
|
||||
targets[label] = targets.get(label, []) + [i]
|
||||
elif op == END_FINALLY and i in self.fixed_jumps:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
'''
|
||||
from __future__ import print_function
|
||||
'''
|
||||
Copyright (c) 1998-2002 John Aycock
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
@@ -8,17 +9,17 @@ Copyright (c) 1998-2002 John Aycock
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
'''
|
||||
|
||||
__version__ = 'SPARK-0.7 (pre-alpha-7) uncompyle trim'
|
||||
@@ -28,31 +29,31 @@ def _namelist(instance):
|
||||
for c in classlist:
|
||||
for b in c.__bases__:
|
||||
classlist.append(b)
|
||||
for name in c.__dict__.keys():
|
||||
if not namedict.has_key(name):
|
||||
for name in list(c.__dict__.keys()):
|
||||
if name not in namedict:
|
||||
namelist.append(name)
|
||||
namedict[name] = 1
|
||||
return namelist
|
||||
|
||||
#
|
||||
# Extracted from GenericParser and made global so that [un]picking works.
|
||||
#
|
||||
class _State:
|
||||
'''
|
||||
Extracted from GenericParser and made global so that [un]picking works.
|
||||
'''
|
||||
def __init__(self, stateno, items):
|
||||
self.T, self.complete, self.items = [], [], items
|
||||
self.stateno = stateno
|
||||
|
||||
class GenericParser:
|
||||
#
|
||||
# An Earley parser, as per J. Earley, "An Efficient Context-Free
|
||||
# Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley,
|
||||
# "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis,
|
||||
# Carnegie-Mellon University, August 1968. New formulation of
|
||||
# the parser according to J. Aycock, "Practical Earley Parsing
|
||||
# and the SPARK Toolkit", Ph.D. thesis, University of Victoria,
|
||||
# 2001, and J. Aycock and R. N. Horspool, "Practical Earley
|
||||
# Parsing", unpublished paper, 2001.
|
||||
#
|
||||
'''
|
||||
An Earley parser, as per J. Earley, "An Efficient Context-Free
|
||||
Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley,
|
||||
"An Efficient Context-Free Parsing Algorithm", Ph.D. thesis,
|
||||
Carnegie-Mellon University, August 1968. New formulation of
|
||||
the parser according to J. Aycock, "Practical Earley Parsing
|
||||
and the SPARK Toolkit", Ph.D. thesis, University of Victoria,
|
||||
2001, and J. Aycock and R. N. Horspool, "Practical Earley
|
||||
Parsing", unpublished paper, 2001.
|
||||
'''
|
||||
|
||||
def __init__(self, start):
|
||||
self.rules = {}
|
||||
@@ -90,7 +91,7 @@ class GenericParser:
|
||||
changes = 1
|
||||
while changes:
|
||||
changes = 0
|
||||
for k, v in self.edges.items():
|
||||
for k, v in list(self.edges.items()):
|
||||
if v is None:
|
||||
state, sym = k
|
||||
if self.states.has_key(state):
|
||||
@@ -127,12 +128,12 @@ class GenericParser:
|
||||
rules = doc.split()
|
||||
|
||||
index = []
|
||||
for i in xrange(len(rules)):
|
||||
for i in range(len(rules)):
|
||||
if rules[i] == '::=':
|
||||
index.append(i-1)
|
||||
index.append(len(rules))
|
||||
|
||||
for i in xrange(len(index)-1):
|
||||
for i in range(len(index)-1):
|
||||
lhs = rules[index[i]]
|
||||
rhs = rules[index[i]+2:index[i+1]]
|
||||
rule = (lhs, tuple(rhs))
|
||||
@@ -140,7 +141,7 @@ class GenericParser:
|
||||
if _preprocess:
|
||||
rule, fn = self.preprocess(rule, func)
|
||||
|
||||
if self.rules.has_key(lhs):
|
||||
if lhs in self.rules:
|
||||
self.rules[lhs].append(rule)
|
||||
else:
|
||||
self.rules[lhs] = [ rule ]
|
||||
@@ -163,7 +164,7 @@ class GenericParser:
|
||||
self.nullable = {}
|
||||
tbd = []
|
||||
|
||||
for rulelist in self.rules.values():
|
||||
for rulelist in list(self.rules.values()):
|
||||
lhs = rulelist[0][0]
|
||||
self.nullable[lhs] = 0
|
||||
for rule in rulelist:
|
||||
@@ -178,7 +179,7 @@ class GenericParser:
|
||||
# grammars.
|
||||
#
|
||||
for sym in rhs:
|
||||
if not self.rules.has_key(sym):
|
||||
if sym not in self.rules:
|
||||
break
|
||||
else:
|
||||
tbd.append(rule)
|
||||
@@ -212,7 +213,7 @@ class GenericParser:
|
||||
|
||||
def makeNewRules(self):
|
||||
worklist = []
|
||||
for rulelist in self.rules.values():
|
||||
for rulelist in list(self.rules.values()):
|
||||
for rule in rulelist:
|
||||
worklist.append((rule, 0, 1, rule))
|
||||
|
||||
@@ -221,7 +222,7 @@ class GenericParser:
|
||||
n = len(rhs)
|
||||
while i < n:
|
||||
sym = rhs[i]
|
||||
if not self.rules.has_key(sym) or \
|
||||
if sym not in self.rules or \
|
||||
not self.nullable[sym]:
|
||||
candidate = 0
|
||||
i = i + 1
|
||||
@@ -238,7 +239,7 @@ class GenericParser:
|
||||
if candidate:
|
||||
lhs = self._NULLABLE+lhs
|
||||
rule = (lhs, rhs)
|
||||
if self.newrules.has_key(lhs):
|
||||
if lhs in self.newrules:
|
||||
self.newrules[lhs].append(rule)
|
||||
else:
|
||||
self.newrules[lhs] = [ rule ]
|
||||
@@ -248,7 +249,7 @@ class GenericParser:
|
||||
return None
|
||||
|
||||
def error(self, token):
|
||||
print "Syntax error at or near `%s' token" % token
|
||||
print("Syntax error at or near `%s' token" % token)
|
||||
raise SystemExit
|
||||
|
||||
def parse(self, tokens):
|
||||
@@ -274,7 +275,7 @@ class GenericParser:
|
||||
else:
|
||||
sets.append([])
|
||||
self.makeSet(None, sets, len(tokens))
|
||||
|
||||
|
||||
finalitem = (self.finalState(tokens), 0)
|
||||
if finalitem not in sets[-2]:
|
||||
if len(tokens) > 0:
|
||||
@@ -292,7 +293,8 @@ class GenericParser:
|
||||
#
|
||||
return self._NULLABLE == sym[0:len(self._NULLABLE)]
|
||||
|
||||
def skip(self, (lhs, rhs), pos=0):
|
||||
def skip(self, xxx_todo_changeme, pos=0):
|
||||
(lhs, rhs) = xxx_todo_changeme
|
||||
n = len(rhs)
|
||||
while pos < n:
|
||||
if not self.isnullable(rhs[pos]):
|
||||
@@ -551,12 +553,12 @@ class GenericParser:
|
||||
rule = self.ambiguity(self.newrules[nt])
|
||||
else:
|
||||
rule = self.newrules[nt][0]
|
||||
#print rule
|
||||
# print(rule)
|
||||
|
||||
rhs = rule[1]
|
||||
attr = [None] * len(rhs)
|
||||
|
||||
for i in xrange(len(rhs)-1, -1, -1):
|
||||
for i in range(len(rhs)-1, -1, -1):
|
||||
attr[i] = self.deriveEpsilon(rhs[i])
|
||||
return self.rule2func[self.new2old[rule]](attr)
|
||||
|
||||
@@ -570,12 +572,12 @@ class GenericParser:
|
||||
rule = choices[0]
|
||||
if len(choices) > 1:
|
||||
rule = self.ambiguity(choices)
|
||||
#print rule
|
||||
# print(rule)
|
||||
|
||||
rhs = rule[1]
|
||||
attr = [None] * len(rhs)
|
||||
|
||||
for i in xrange(len(rhs)-1, -1, -1):
|
||||
for i in range(len(rhs)-1, -1, -1):
|
||||
sym = rhs[i]
|
||||
if not self.newrules.has_key(sym):
|
||||
if sym != self._BOF:
|
||||
@@ -599,24 +601,23 @@ class GenericParser:
|
||||
# appears in >1 method. Also undefined results if rules
|
||||
# causing the ambiguity appear in the same method.
|
||||
#
|
||||
|
||||
sortlist = []
|
||||
name2index = {}
|
||||
for i in xrange(len(rules)):
|
||||
for i in range(len(rules)):
|
||||
lhs, rhs = rule = rules[i]
|
||||
name = self.rule2name[self.new2old[rule]]
|
||||
sortlist.append((len(rhs), name))
|
||||
name2index[name] = i
|
||||
sortlist.sort()
|
||||
list = map(lambda (a,b): b, sortlist)
|
||||
list = [a_b[1] for a_b in sortlist]
|
||||
return rules[name2index[self.resolve(list)]]
|
||||
|
||||
def resolve(self, list):
|
||||
#
|
||||
# Resolve ambiguity in favor of the shortest RHS.
|
||||
# Since we walk the tree from the top down, this
|
||||
# should effectively resolve in favor of a "shift".
|
||||
#
|
||||
'''
|
||||
Resolve ambiguity in favor of the shortest RHS.
|
||||
Since we walk the tree from the top down, this
|
||||
should effectively resolve in favor of a "shift".
|
||||
'''
|
||||
return list[0]
|
||||
|
||||
#
|
||||
@@ -645,28 +646,29 @@ class GenericASTBuilder(GenericParser):
|
||||
if isinstance(arg, self.AST):
|
||||
children.append(arg)
|
||||
else:
|
||||
children.append(arg)
|
||||
children.append(self.terminal(arg))
|
||||
return self.nonterminal(lhs, children)
|
||||
|
||||
def terminal(self, token): return token
|
||||
|
||||
def nonterminal(self, type, args):
|
||||
rv = self.AST(type)
|
||||
rv[:len(args)] = args
|
||||
return rv
|
||||
|
||||
#
|
||||
# GenericASTTraversal is a Visitor pattern according to Design Patterns. For
|
||||
# each node it attempts to invoke the method n_<node type>, falling
|
||||
# back onto the default() method if the n_* can't be found. The preorder
|
||||
# traversal also looks for an exit hook named n_<node type>_exit (no default
|
||||
# routine is called if it's not found). To prematurely halt traversal
|
||||
# of a subtree, call the prune() method -- this only makes sense for a
|
||||
# preorder traversal. Node type is determined via the typestring() method.
|
||||
#
|
||||
|
||||
class GenericASTTraversalPruningException:
|
||||
pass
|
||||
|
||||
class GenericASTTraversal:
|
||||
'''
|
||||
GenericASTTraversal is a Visitor pattern according to Design Patterns. For
|
||||
each node it attempts to invoke the method n_<node type>, falling
|
||||
back onto the default() method if the n_* can't be found. The preorder
|
||||
traversal also looks for an exit hook named n_<node type>_exit (no default
|
||||
routine is called if it's not found). To prematurely halt traversal
|
||||
of a subtree, call the prune() method -- this only makes sense for a
|
||||
preorder traversal. Node type is determined via the typestring() method.
|
||||
'''
|
||||
def __init__(self, ast):
|
||||
self.ast = ast
|
||||
|
||||
|
Reference in New Issue
Block a user