diff --git a/bin/uncompyle6 b/bin/uncompyle6 index f26d5a48..b1b71cc7 100755 --- a/bin/uncompyle6 +++ b/bin/uncompyle6 @@ -32,8 +32,9 @@ Options: --help show this message Debugging Options: - --showasm -a include byte-code (disables --verify) - --showast -t include AST (abstract syntax tree) (disables --verify) + --asm -a include byte-code (disables --verify) + --grammar -g show matching grammar + --treee -t include syntax tree (disables --verify) Extensions of generated files: '.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify) @@ -51,7 +52,7 @@ from uncompyle6.main import main, status_msg def usage(): print("""usage: - %s [--help] [--verify] [--showasm] [--showast] [-o ] FILE|DIR... + %s [--help] [--verify] [--asm] [--tree] [--grammar] [-o ] FILE|DIR... """ % program) sys.exit(1) @@ -67,33 +68,37 @@ timestamp = True timestampfmt = "# %Y.%m.%d %H:%M:%S %Z" try: - opts, files = getopt.getopt(sys.argv[1:], 'hatdro:c:p:', - ['help', 'verify', 'showast', 'showasm']) + opts, files = getopt.getopt(sys.argv[1:], 'hagtdro:c:p:', + 'help asm grammar recurse timestamp tree verify ' + 'showgrammar'.split(' ')) except getopt.GetoptError as e: print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr) sys.exit(-1) +options = {} for opt, val in opts: if opt in ('-h', '--help'): print(__doc__) sys.exit(0) elif opt == '--verify': - do_verify = True - elif opt in ('--showasm', '-a'): - showasm = True - do_verify = False - elif opt in ('--showast', '-t'): - showast = True - do_verify = False + options['do_verify'] = True + elif opt in ('--asm', '-a'): + options['showasm'] = True + options['do_verify'] = False + elif opt in ('--tree', '-t'): + options['showast'] = True + options['do_verify'] = False + elif opt in ('--grammar', '-g'): + options['showgrammar'] = True elif opt == '-o': outfile = val - elif opt == '-d': + elif opt == ('--timestamp', '-d'): timestamp = False elif opt == '-c': codes.append(val) elif opt == '-p': numproc = int(val) - elif opt == '-r': + elif opt == ('--recurse', '-r'): recurse_dirs = True else: print(opt, file=sys.stderr) @@ -137,8 +142,8 @@ if timestamp: print(time.strftime(timestampfmt)) if numproc <= 1: try: - result = main(src_base, out_base, files, codes, outfile, showasm, - showast, do_verify) + result = main(src_base, out_base, files, codes, outfile, + **options) if len(files) > 1: mess = status_msg(do_verify, *result) print('# ' + mess) @@ -171,7 +176,7 @@ else: if f is None: break (t, o, f, v) = \ - main(src_base, out_base, [f], codes, outfile, showasm, showast, do_verify) + main(src_base, out_base, [f], codes, outfile, **options) tot_files += t okay_files += o failed_files += f diff --git a/pytest/test_disasm.py b/pytest/test_disasm.py index d0a36caa..2b7ec22a 100644 --- a/pytest/test_disasm.py +++ b/pytest/test_disasm.py @@ -13,11 +13,11 @@ os.chdir(src_dir) @pytest.mark.parametrize(("test_tuple", "function_to_test"), [ ( - ('../test/bytecode_2.7/if.pyc', 'testdata/if-2.7.right',), + ('../test/bytecode_2.7/05_if.pyc', 'testdata/if-2.7.right',), disassemble_file ), ( - ('../test/bytecode_2.7/ifelse.pyc', 'testdata/ifelse-2.7.right',), + ('../test/bytecode_2.7/05_ifelse.pyc', 'testdata/ifelse-2.7.right',), disassemble_file ), ]) diff --git a/pytest/testdata/if-2.7.right b/pytest/testdata/if-2.7.right index 19a3ac61..3591a24a 100644 --- a/pytest/testdata/if-2.7.right +++ b/pytest/testdata/if-2.7.right @@ -1,10 +1,10 @@ # Python 2.7 -# Embedded file name: ./source_3.4/branching/if.py +# Embedded file name: simple_source/branching/05_if.py - 1 0 LOAD_NAME 'a' + 6 0 LOAD_NAME 'True' 3 POP_JUMP_IF_FALSE '15' - 2 6 LOAD_NAME 'c' + 7 6 LOAD_NAME 'False' 9 STORE_NAME 'b' 12 JUMP_FORWARD '15' 15_0 COME_FROM '12' diff --git a/pytest/testdata/ifelse-2.7.right b/pytest/testdata/ifelse-2.7.right index 120b901b..223f0a04 100644 --- a/pytest/testdata/ifelse-2.7.right +++ b/pytest/testdata/ifelse-2.7.right @@ -1,14 +1,14 @@ # Python 2.7 -# Embedded file name: ./source_3.4/branching/ifelse.py +# Embedded file name: simple_source/branching/05_ifelse.py - 1 0 LOAD_NAME 'a' + 3 0 LOAD_NAME 'True' 3 POP_JUMP_IF_FALSE '15' - 2 6 LOAD_NAME 'c' + 4 6 LOAD_CONST 1 9 STORE_NAME 'b' 12 JUMP_FORWARD '21' - 4 15 LOAD_NAME 'e' + 6 15 LOAD_CONST 2 18 STORE_NAME 'd' 21_0 COME_FROM '12' 21 LOAD_CONST '' diff --git a/test/Makefile b/test/Makefile index 8c34983b..07c8e6dc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -46,9 +46,9 @@ check-bytecode-2.7: check-bytecode-3.2: $(PYTHON) test_pythonlib.py --bytecode-3.2 -#: Check deparsing Python 3.2 +#: Check deparsing Python 3.4 check-bytecode-3.4: - $(PYTHON) test_pythonlib.py --bytecode-3.2 + $(PYTHON) test_pythonlib.py --bytecode-3.4 #: short tests for bytecodes only for this version of Python check-native-short: diff --git a/test/add-test.py b/test/add-test.py new file mode 100755 index 00000000..85a64022 --- /dev/null +++ b/test/add-test.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +""" Trivial helper program to bytecompile and run an uncompile +""" +import os, sys, py_compile +assert len(sys.argv) == 2 +path = sys.argv[1] +short = os.path.basename(path) +version = sys.version[0:3] +cfile = "bytecode_%s/%s" % (version, short) + 'c' +print("byte-compiling %s to %s" % (path, cfile)) +py_compile.compile(path, cfile) +os.system("../bin/uncompyle6 -a -t %s" % cfile) diff --git a/test/bytecode_2.7/00_assign.pyc b/test/bytecode_2.7/00_assign.pyc new file mode 100644 index 00000000..65ffc805 Binary files /dev/null and b/test/bytecode_2.7/00_assign.pyc differ diff --git a/test/bytecode_2.7/01-lc.pyc b/test/bytecode_2.7/01-lc.pyc deleted file mode 100644 index 9ac619fd..00000000 Binary files a/test/bytecode_2.7/01-lc.pyc and /dev/null differ diff --git a/test/bytecode_2.7/01-slice.pyc b/test/bytecode_2.7/01-slice.pyc deleted file mode 100644 index 4410ecad..00000000 Binary files a/test/bytecode_2.7/01-slice.pyc and /dev/null differ diff --git a/test/bytecode_2.7/01_list_comprehension.pyc b/test/bytecode_2.7/01_list_comprehension.pyc new file mode 100644 index 00000000..a412cca3 Binary files /dev/null and b/test/bytecode_2.7/01_list_comprehension.pyc differ diff --git a/test/bytecode_2.7/01_positional.pyc b/test/bytecode_2.7/01_positional.pyc new file mode 100644 index 00000000..ca806113 Binary files /dev/null and b/test/bytecode_2.7/01_positional.pyc differ diff --git a/test/bytecode_2.7/05_if.pyc b/test/bytecode_2.7/05_if.pyc new file mode 100644 index 00000000..4b079d76 Binary files /dev/null and b/test/bytecode_2.7/05_if.pyc differ diff --git a/test/bytecode_2.7/05_ifelse.pyc b/test/bytecode_2.7/05_ifelse.pyc new file mode 100644 index 00000000..e73cb98e Binary files /dev/null and b/test/bytecode_2.7/05_ifelse.pyc differ diff --git a/test/bytecode_2.7/10_keyword.pyc b/test/bytecode_2.7/10_keyword.pyc new file mode 100644 index 00000000..3f25f909 Binary files /dev/null and b/test/bytecode_2.7/10_keyword.pyc differ diff --git a/test/bytecode_2.7/10_try_except.pyc b/test/bytecode_2.7/10_try_except.pyc new file mode 100644 index 00000000..c7999b3f Binary files /dev/null and b/test/bytecode_2.7/10_try_except.pyc differ diff --git a/test/bytecode_2.7/15_assert.pyc b/test/bytecode_2.7/15_assert.pyc new file mode 100644 index 00000000..ee0092f2 Binary files /dev/null and b/test/bytecode_2.7/15_assert.pyc differ diff --git a/test/bytecode_2.7/20_try_except.pyc b/test/bytecode_2.7/20_try_except.pyc new file mode 100644 index 00000000..01af3fd1 Binary files /dev/null and b/test/bytecode_2.7/20_try_except.pyc differ diff --git a/test/bytecode_2.7/25_try_except.pyc b/test/bytecode_2.7/25_try_except.pyc new file mode 100644 index 00000000..f5cde2e0 Binary files /dev/null and b/test/bytecode_2.7/25_try_except.pyc differ diff --git a/test/bytecode_2.7/assert.pyc b/test/bytecode_2.7/assert.pyc deleted file mode 100644 index f2630b11..00000000 Binary files a/test/bytecode_2.7/assert.pyc and /dev/null differ diff --git a/test/bytecode_2.7/assign.pyc b/test/bytecode_2.7/assign.pyc deleted file mode 100644 index 6c0ebc5c..00000000 Binary files a/test/bytecode_2.7/assign.pyc and /dev/null differ diff --git a/test/bytecode_2.7/if.pyc b/test/bytecode_2.7/if.pyc deleted file mode 100644 index 97c3ef13..00000000 Binary files a/test/bytecode_2.7/if.pyc and /dev/null differ diff --git a/test/bytecode_2.7/ifelse.pyc b/test/bytecode_2.7/ifelse.pyc deleted file mode 100644 index b2038018..00000000 Binary files a/test/bytecode_2.7/ifelse.pyc and /dev/null differ diff --git a/test/bytecode_2.7/keyword.pyc b/test/bytecode_2.7/keyword.pyc deleted file mode 100644 index 873daf17..00000000 Binary files a/test/bytecode_2.7/keyword.pyc and /dev/null differ diff --git a/test/bytecode_2.7/positional.pyc b/test/bytecode_2.7/positional.pyc deleted file mode 100644 index 70a08e85..00000000 Binary files a/test/bytecode_2.7/positional.pyc and /dev/null differ diff --git a/test/bytecode_3.4/02_slice.pyc b/test/bytecode_3.4/02_slice.pyc new file mode 100644 index 00000000..fbf24a37 Binary files /dev/null and b/test/bytecode_3.4/02_slice.pyc differ diff --git a/test/bytecode_3.4/05_if.pyc b/test/bytecode_3.4/05_if.pyc new file mode 100644 index 00000000..12a4eccd Binary files /dev/null and b/test/bytecode_3.4/05_if.pyc differ diff --git a/test/bytecode_3.4/05_ifelse.pyc b/test/bytecode_3.4/05_ifelse.pyc new file mode 100644 index 00000000..85cfc88e Binary files /dev/null and b/test/bytecode_3.4/05_ifelse.pyc differ diff --git a/test/bytecode_3.4/10_keyword.pyc b/test/bytecode_3.4/10_keyword.pyc new file mode 100644 index 00000000..f9529d32 Binary files /dev/null and b/test/bytecode_3.4/10_keyword.pyc differ diff --git a/test/bytecode_3.4/10_mixed_boolean.pyc b/test/bytecode_3.4/10_mixed_boolean.pyc new file mode 100644 index 00000000..ca6b6d6b Binary files /dev/null and b/test/bytecode_3.4/10_mixed_boolean.pyc differ diff --git a/test/bytecode_3.4/15_assert.pyc b/test/bytecode_3.4/15_assert.pyc new file mode 100644 index 00000000..5b5632b4 Binary files /dev/null and b/test/bytecode_3.4/15_assert.pyc differ diff --git a/test/bytecode_3.4/25_try_except.pyc b/test/bytecode_3.4/25_try_except.pyc new file mode 100644 index 00000000..6665743c Binary files /dev/null and b/test/bytecode_3.4/25_try_except.pyc differ diff --git a/test/bytecode_3.4/add.pyc b/test/bytecode_3.4/add.pyc deleted file mode 100644 index e03b6825..00000000 Binary files a/test/bytecode_3.4/add.pyc and /dev/null differ diff --git a/test/bytecode_3.4/and.pyc b/test/bytecode_3.4/and.pyc deleted file mode 100644 index 10c00e52..00000000 Binary files a/test/bytecode_3.4/and.pyc and /dev/null differ diff --git a/test/bytecode_3.4/assert.pyc b/test/bytecode_3.4/assert.pyc deleted file mode 100644 index dcdc3b4d..00000000 Binary files a/test/bytecode_3.4/assert.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex1.pyc b/test/bytecode_3.4/complex1.pyc deleted file mode 100644 index ce76eafd..00000000 Binary files a/test/bytecode_3.4/complex1.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex2.pyc b/test/bytecode_3.4/complex2.pyc deleted file mode 100644 index 62eebcbe..00000000 Binary files a/test/bytecode_3.4/complex2.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex3.pyc b/test/bytecode_3.4/complex3.pyc deleted file mode 100644 index 968b8256..00000000 Binary files a/test/bytecode_3.4/complex3.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex4.pyc b/test/bytecode_3.4/complex4.pyc deleted file mode 100644 index 74b08190..00000000 Binary files a/test/bytecode_3.4/complex4.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex5.pyc b/test/bytecode_3.4/complex5.pyc deleted file mode 100644 index 1e9190ab..00000000 Binary files a/test/bytecode_3.4/complex5.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex6.pyc b/test/bytecode_3.4/complex6.pyc deleted file mode 100644 index 1324c129..00000000 Binary files a/test/bytecode_3.4/complex6.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex7.pyc b/test/bytecode_3.4/complex7.pyc deleted file mode 100644 index c8b0504c..00000000 Binary files a/test/bytecode_3.4/complex7.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex8.pyc b/test/bytecode_3.4/complex8.pyc deleted file mode 100644 index f9c0e50b..00000000 Binary files a/test/bytecode_3.4/complex8.pyc and /dev/null differ diff --git a/test/bytecode_3.4/complex9.pyc b/test/bytecode_3.4/complex9.pyc deleted file mode 100644 index ec34d9d4..00000000 Binary files a/test/bytecode_3.4/complex9.pyc and /dev/null differ diff --git a/test/bytecode_3.4/if.pyc b/test/bytecode_3.4/if.pyc deleted file mode 100644 index 6e346c8e..00000000 Binary files a/test/bytecode_3.4/if.pyc and /dev/null differ diff --git a/test/bytecode_3.4/ifelse.pyc b/test/bytecode_3.4/ifelse.pyc deleted file mode 100644 index 34195d47..00000000 Binary files a/test/bytecode_3.4/ifelse.pyc and /dev/null differ diff --git a/test/bytecode_3.4/keyword.pyc b/test/bytecode_3.4/keyword.pyc deleted file mode 100644 index aa97f8b4..00000000 Binary files a/test/bytecode_3.4/keyword.pyc and /dev/null differ diff --git a/test/bytecode_3.4/positional.pyc b/test/bytecode_3.4/positional.pyc deleted file mode 100644 index 3a15b134..00000000 Binary files a/test/bytecode_3.4/positional.pyc and /dev/null differ diff --git a/test/simple_source/branching/05_if.py b/test/simple_source/branching/05_if.py new file mode 100644 index 00000000..acc65a7f --- /dev/null +++ b/test/simple_source/branching/05_if.py @@ -0,0 +1,7 @@ +# Tests: + +# ifstmt ::= testexpr _ifstmts_jump +# _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM + +if True: + b = False diff --git a/test/simple_source/branching/05_ifelse.py b/test/simple_source/branching/05_ifelse.py new file mode 100644 index 00000000..6f1332b4 --- /dev/null +++ b/test/simple_source/branching/05_ifelse.py @@ -0,0 +1,9 @@ +# Tests: + +# ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM +# else_suite ::= suite_stmts + +if True: + b = 1 +else: + d = 2 diff --git a/test/simple_source/branching/if.py b/test/simple_source/branching/if.py deleted file mode 100644 index 59bcb560..00000000 --- a/test/simple_source/branching/if.py +++ /dev/null @@ -1,4 +0,0 @@ -# Tests: -# ifstmt ::= testexpr _ifstmts_jump -if a: - b = c diff --git a/test/simple_source/branching/ifelse.py b/test/simple_source/branching/ifelse.py deleted file mode 100644 index 1f21e49b..00000000 --- a/test/simple_source/branching/ifelse.py +++ /dev/null @@ -1,7 +0,0 @@ - -# Tests -# ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite COME_FROM -if a: - b = c -else: - d = e diff --git a/test/simple_source/call_arguments/positional.py b/test/simple_source/call_arguments/01_positional.py similarity index 94% rename from test/simple_source/call_arguments/positional.py rename to test/simple_source/call_arguments/01_positional.py index 8cc6eaba..3cc17e25 100644 --- a/test/simple_source/call_arguments/positional.py +++ b/test/simple_source/call_arguments/01_positional.py @@ -2,4 +2,4 @@ # expr ::= expr {expr}^n CALL_FUNCTION_n # which in the specifc case below is: # expr ::= expr expr expr CALL_FUNCTION_2 -a(b, c) +max(1, 2) diff --git a/test/simple_source/call_arguments/10_keyword.py b/test/simple_source/call_arguments/10_keyword.py new file mode 100644 index 00000000..82413c61 --- /dev/null +++ b/test/simple_source/call_arguments/10_keyword.py @@ -0,0 +1,8 @@ +# Tests: +# +# call_stmt ::= expr POP_TOP +# build_list ::= expr expr BUILD_LIST_2 +# kwarg ::= LOAD_CONST expr +# call_function ::= expr expr kwarg kwarg CALL_FUNCTION_513 + +sorted([1,2], reverse=True, key=None) diff --git a/test/simple_source/call_arguments/keyword.py b/test/simple_source/call_arguments/keyword.py deleted file mode 100644 index b2ef32d2..00000000 --- a/test/simple_source/call_arguments/keyword.py +++ /dev/null @@ -1 +0,0 @@ -a = b(c=d, e=f) diff --git a/test/simple_source/exception/20_try_except.py b/test/simple_source/exception/20_try_except.py index 70b8e052..ce5313c1 100644 --- a/test/simple_source/exception/20_try_except.py +++ b/test/simple_source/exception/20_try_except.py @@ -1,3 +1,11 @@ +# Tests: +# forstmt ::= SETUP_LOOP expr _for designator for_block POP_BLOCK COME_FROM +# for_block ::= l_stmts_opt JUMP_BACK +# trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM +# try_middle ::= jmp_abs COME_FROM except_stmts END_FINALLY + +# Had a bug with the end of the except matching the end of the +# for loop. for i in (1,2): try: x = 1 diff --git a/test/simple_source/exception/25_try_except.py b/test/simple_source/exception/25_try_except.py new file mode 100644 index 00000000..31763ae4 --- /dev/null +++ b/test/simple_source/exception/25_try_except.py @@ -0,0 +1,21 @@ +# Tests: +# +# tryfinallystmt ::= SETUP_FINALLY suite_stmts POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt END_FINALLY +# suite_stmts_opt ::= suite_stmts +# trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM +# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM +# except_stmt ::= except_cond1 except_suite +# except_cond1 ::= DUP_TOP expr COMPARE_OP jmp_false POP_TOP POP_TOP POP_TOP +# trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM +# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM +# except_cond1 ::= DUP_TOP expr COMPARE_OP jmp_false POP_TOP POP_TOP POP_TOP +try: + try: + x = 1 + except AssertionError: + x = 2 + +except ImportError: + x = 3 +finally: + x = 4 diff --git a/test/simple_source/misc/assert.py b/test/simple_source/misc/assert.py deleted file mode 100644 index 92527b02..00000000 --- a/test/simple_source/misc/assert.py +++ /dev/null @@ -1,5 +0,0 @@ -# Tests: -# assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 -# callfunction ::= ... - -assert isinstance(1, int) diff --git a/test/simple_source/misc/assign_none.py b/test/simple_source/misc/assign_none.py deleted file mode 100644 index 22c517c7..00000000 --- a/test/simple_source/misc/assign_none.py +++ /dev/null @@ -1 +0,0 @@ -vario = None diff --git a/test/simple_source/operation_logic/01_boolean.py b/test/simple_source/operation_logic/01_boolean.py new file mode 100644 index 00000000..20f8a1e1 --- /dev/null +++ b/test/simple_source/operation_logic/01_boolean.py @@ -0,0 +1,2 @@ +1 and 0 +1 or 0 diff --git a/test/simple_source/operation_logic/10_mixed_boolean.py b/test/simple_source/operation_logic/10_mixed_boolean.py new file mode 100644 index 00000000..d0851a63 --- /dev/null +++ b/test/simple_source/operation_logic/10_mixed_boolean.py @@ -0,0 +1,12 @@ +b = True +c = False +d = True +a = b and c or d +a = (b or c) and d +a = b or c or d +a = b and c and d +a = b or c and d +a = b and (c or d) +a = b and c or d +a = (b or c and d) and b +a = (b or c and d or a) and b diff --git a/test/simple_source/operation_logic/or.py b/test/simple_source/operation_logic/or.py deleted file mode 100644 index de3a14d5..00000000 --- a/test/simple_source/operation_logic/or.py +++ /dev/null @@ -1 +0,0 @@ -a = b or c diff --git a/test/simple_source/simple_stmts/15_assert.py b/test/simple_source/simple_stmts/15_assert.py new file mode 100644 index 00000000..837541b7 --- /dev/null +++ b/test/simple_source/simple_stmts/15_assert.py @@ -0,0 +1,5 @@ +# Tests: +# assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 +# call_function ::= expr expr expr CALL_FUNCTION_2 + +assert isinstance(1, int) diff --git a/test/simple_source/slice/01_slice.py b/test/simple_source/slice/02_slice.py similarity index 73% rename from test/simple_source/slice/01_slice.py rename to test/simple_source/slice/02_slice.py index 2760f09a..c181d5ca 100644 --- a/test/simple_source/slice/01_slice.py +++ b/test/simple_source/slice/02_slice.py @@ -1,2 +1,3 @@ ary = [1,2,3] ary[:2] +ary[2:] diff --git a/uncompyle6/main.py b/uncompyle6/main.py index bceb17ee..dbbcbc1b 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -9,7 +9,8 @@ from uncompyle6.scanner import get_scanner from uncompyle6.load import load_module # FIXME: remove duplicate code from deparse_code -def uncompyle(version, co, out=None, showasm=False, showast=False): +def uncompyle(version, co, out=None, showasm=False, showast=False, + showgrammar=False): """ disassembles and deparses a given code block 'co' """ @@ -32,7 +33,8 @@ def uncompyle(version, co, out=None, showasm=False, showast=False): print(file=out) # Build AST from disassembly. - walk = pysource.Walker(version, out, scanner, showast=showast) + walk = pysource.Walker(version, out, scanner, + showast=showast, showgrammar=showgrammar) try: ast = walk.build_ast(tokens, customize) except pysource.ParserError as e : # parser failed, dump disassembly diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 60a43d17..a1843ce4 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -19,13 +19,13 @@ from __future__ import print_function from uncompyle6.parser import PythonParser, nop_func from uncompyle6.parsers.astnode import AST -from uncompyle6.parsers.spark import GenericASTBuilder +from uncompyle6.parsers.spark import GenericASTBuilder, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG class Python3Parser(PythonParser): - def __init__(self): + def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG): self.added_rules = set() - GenericASTBuilder.__init__(self, AST, 'stmts') + GenericASTBuilder.__init__(self, AST, 'stmts', debug=debug_parser) self.new_rules = set() def add_unique_rule(self, rule, opname, count, customize): diff --git a/uncompyle6/parsers/spark.py b/uncompyle6/parsers/spark.py index 5f32dcea..743d20e1 100644 --- a/uncompyle6/parsers/spark.py +++ b/uncompyle6/parsers/spark.py @@ -45,7 +45,9 @@ class _State: self.stateno = stateno # DEFAULT_DEBUG = {'rules': True, 'transition': True, 'reduce' : True} +# DEFAULT_DEBUG = {'rules': False, 'transition': False, 'reduce' : True} DEFAULT_DEBUG = {'rules': False, 'transition': False, 'reduce': False} + class GenericParser: ''' An Earley parser, as per J. Earley, "An Efficient Context-Free @@ -640,7 +642,7 @@ class GenericParser: # class GenericASTBuilder(GenericParser): - def __init__(self, AST, start): + def __init__(self, AST, start, debug=DEFAULT_DEBUG): GenericParser.__init__(self, start) self.AST = AST diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index 9faa788d..159a04de 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -68,7 +68,7 @@ import inspect, sys, re from uncompyle6 import PYTHON3 from uncompyle6.parser import get_python_parser from uncompyle6.parsers.astnode import AST -from uncompyle6.parsers.spark import GenericASTTraversal +from uncompyle6.parsers.spark import GenericASTTraversal, DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from uncompyle6.scanner import Code, get_scanner from uncompyle6.scanners.tok import Token, NoneToken import uncompyle6.parser as python_parser @@ -470,7 +470,7 @@ def find_none(node): class Walker(GenericASTTraversal, object): stacked_params = ('f', 'indent', 'isLambda', '_globals') - def __init__(self, version, out, scanner, showast=False): + def __init__(self, version, out, scanner, showast=False, showgrammar=False): GenericASTTraversal.__init__(self, ast=None) self.scanner = scanner params = { @@ -1532,7 +1532,8 @@ class Walker(GenericASTTraversal, object): return ast -def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False): +def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False, + showgrammar=False): """ disassembles and deparses a given code block 'co' """ @@ -1547,6 +1548,10 @@ def deparse_code(version, co, out=sys.stdout, showasm=False, showast=False): for t in tokens: print(t) + parser_debug = dict(PARSER_DEFAULT_DEBUG) + parser_debug['reduce'] = showgrammar + + # Build AST from disassembly. walk = Walker(version, out, scanner, showast=showast)