diff --git a/test/dis-compare.py b/test/dis-compare.py index 5c891614..bdbb8694 100755 --- a/test/dis-compare.py +++ b/test/dis-compare.py @@ -51,8 +51,6 @@ def compare_ok(version, co): for good_line in good_lines: if '\tCOME_FROM ' in got_lines[i]: i += 1 - if '\tJUMP_FORWARD ' in good_line: - good_line = good_line = good_line[:32] + good_line[35:] if got_lines[i] != good_line: print('line %d %s' % (i+1, ('=' * 30))) diff --git a/test/simple-uncompyle-code-test.py b/test/simple-uncompyle-code-test.py index 7b9df457..732084e5 100755 --- a/test/simple-uncompyle-code-test.py +++ b/test/simple-uncompyle-code-test.py @@ -5,14 +5,6 @@ from __future__ import print_function from uncompyle6 import uncompyle import sys, inspect -if (sys.version_info > (3, 0)): - from io import StringIO -else: - from StringIO import StringIO - -from collections import namedtuple -NodeInfo = namedtuple("NodeInfo", "node start finish") - def uncompyle_test(): frame = inspect.currentframe() try: diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index a62763f5..06a8cdfd 100644 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -37,6 +37,7 @@ PYTHON_VERSION = sys.version_info.major + (sys.version_info.minor / 10.0) PYTHON3 = (sys.version_info >= (3, 0)) import uncompyle6 +from uncompyle6.scanner import get_scanner import uncompyle6.marsh from uncompyle6 import walker, verify, magics @@ -118,23 +119,7 @@ def uncompyle(version, co, out=None, showasm=False, showast=False): print('# Embedded file name: %s' % co.co_filename, file=real_out) - # Pick up appropriate scanner - if version == 2.7: - import uncompyle6.scanners.scanner27 as scan - scanner = scan.Scanner27() - elif version == 2.6: - import uncompyle6.scanners.scanner26 as scan - scanner = scan.Scanner26() - elif version == 2.5: - import uncompyle6.scanners.scanner25 as scan - scanner = scan.Scanner25() - elif version == 3.2: - import uncompyle6.scanners.scanner32 as scan - scanner = scan.Scanner32() - elif version == 3.4: - import uncompyle6.scanners.scanner34 as scan - scanner = scan.Scanner34() - scanner.setShowAsm(showasm, out) + scanner = get_scanner(version) tokens, customize = scanner.disassemble(co) if showasm: @@ -143,7 +128,7 @@ def uncompyle(version, co, out=None, showasm=False, showast=False): print(file=out) # Build AST from disassembly. - walk = walker.Walker(out, scanner, showast=showast) + walk = walker.Walker(version, out, scanner, showast=showast) try: ast = walk.build_ast(tokens, customize) except walker.ParserError as e : # parser failed, dump disassembly diff --git a/uncompyle6/deparser.py b/uncompyle6/deparser.py index 3a96524d..32734445 100644 --- a/uncompyle6/deparser.py +++ b/uncompyle6/deparser.py @@ -48,7 +48,11 @@ from __future__ import print_function +import inspect, re, sys + +from uncompyle6 import PYTHON3 from uncompyle6 import walker +from uncompyle6.parser import get_python_parser from uncompyle6.walker import escape, PRECEDENCE, minint from uncompyle6.walker import AST, NONE, find_all_globals from uncompyle6.walker import find_globals, find_none, INDENT_PER_LEVEL @@ -56,18 +60,14 @@ from uncompyle6.walker import ParserError from uncompyle6 import parser from uncompyle6.scanner import Token, Code, get_scanner -try: - from StringIO import StringIO -except ImportError: +if PYTHON3: from io import StringIO - -import sys, inspect, re - +else: + from StringIO import StringIO # FIXME: remove uncompyle dups # from uncompyle6.walker import find_all_globals, find_globals, find_none -from uncompyle6.spark import GenericASTTraversal -from uncompyle6.spark import GenericASTTraversalPruningException +from uncompyle6.parsers.spark import GenericASTTraversal, GenericASTTraversalPruningException from types import CodeType from collections import namedtuple @@ -78,10 +78,14 @@ ExtractInfo = namedtuple("ExtractInfo", class Traverser(walker.Walker, object): stacked_params = ('f', 'indent', 'isLambda', '_globals') - def __init__(self, scanner, showast=0): + def __init__(self, version, scanner, showast=False): GenericASTTraversal.__init__(self, ast=None) self.scanner = scanner - params = {'f': StringIO(), 'indent': '', } + params = { + 'f': StringIO(), + 'indent': '', + } + self.p = get_python_parser(version) self.showast = showast self.__params = params self.__param_stack = [] @@ -550,7 +554,7 @@ class Traverser(walker.Walker, object): if isLambda: tokens.append(Token('LAMBDA_MARKER')) try: - ast = parser.parse(tokens, customize) + ast = parser.parse(self.p, tokens, customize) except parser.ParserError as e: raise ParserError(e, tokens) if self.showast: @@ -566,7 +570,7 @@ class Traverser(walker.Walker, object): # Build AST from disassembly. try: - ast = parser.parse(tokens, customize) + ast = parser.parse(self.p, tokens, customize) except parser.ParserError as e: raise ParserError(e, tokens) @@ -1107,7 +1111,7 @@ class Traverser(walker.Walker, object): pass -def deparse(version, co, out=StringIO(), showasm=0, showast=0): +def deparse(version, co, out=StringIO(), showasm=False, showast=False): assert inspect.iscode(co) # store final output stream for case of error __real_out = out or sys.stdout @@ -1116,7 +1120,7 @@ def deparse(version, co, out=StringIO(), showasm=0, showast=0): # Build AST from disassembly. # walk = walker.Walker(out, scanner, showast=showast) - walk = Traverser(scanner, showast=showast) + walk = Traverser(version, scanner, showast=showast) try: walk.ast = walk.build_ast_d(tokens, customize) @@ -1144,7 +1148,7 @@ if __name__ == '__main__': def deparse_test(co): sys_version = sys.version_info.major + (sys.version_info.minor / 10.0) - walk = deparse(sys_version, co, showasm=1, showast=1) + walk = deparse(sys_version, co, showasm=True, showast=True) print("deparsed source") print(walk.text, "\n") print('------------------------') diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index b9266dc5..adb002a7 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -3,19 +3,32 @@ # Copyright (c) 2005 by Dan Pascu # Copyright (c) 2015 Rocky Bernstein """ -Spark parser for Python. +Common spark parser routines Python. """ +from __future__ import print_function + from uncompyle6 import PYTHON3 -from uncompyle6.spark import GenericASTBuilder import sys + +from uncompyle6.parsers.spark import GenericASTBuilder + if PYTHON3: intern = sys.intern from collections import UserList else: from UserList import UserList +class ParserError(Exception): + def __init__(self, token, offset): + self.token = token + self.offset = offset + + def __str__(self): + return "Syntax error at or near `%r' token at offset %s\n" % \ + (self.token, self.offset) + class AST(UserList): def __init__(self, type, kids=[]): self.type = intern(type) @@ -38,22 +51,7 @@ class AST(UserList): rv = rv + '\n' + str(k).replace('\n', '\n ') return rv - -class ParserError(Exception): - def __init__(self, token, offset): - self.token = token - self.offset = offset - - 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 = {} +class PythonParser(GenericASTBuilder): def cleanup(self): """ @@ -72,625 +70,6 @@ class Parser(GenericASTBuilder): def typestring(self, token): return token.type - def p_funcdef(self, args): - ''' - stmt ::= funcdef - funcdef ::= mkfunc designator - stmt ::= funcdefdeco - funcdefdeco ::= mkfuncdeco designator - mkfuncdeco ::= expr mkfuncdeco CALL_FUNCTION_1 - mkfuncdeco ::= expr mkfuncdeco0 CALL_FUNCTION_1 - mkfuncdeco0 ::= mkfunc - load_closure ::= load_closure LOAD_CLOSURE - load_closure ::= LOAD_CLOSURE - ''' - - def p_list_comprehension(self, args): - ''' - expr ::= list_compr - list_compr ::= BUILD_LIST_0 list_iter - - list_iter ::= list_for - list_iter ::= list_if - list_iter ::= list_if_not - list_iter ::= lc_body - - _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 - - 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 - comp_iter ::= comp_body - comp_body ::= set_comp_body - comp_body ::= gen_comp_body - comp_body ::= dict_comp_body - set_comp_body ::= expr SET_ADD - gen_comp_body ::= expr YIELD_VALUE POP_TOP - dict_comp_body ::= expr expr MAP_ADD - - comp_if ::= expr jmp_false comp_iter - comp_ifnot ::= expr jmp_true comp_iter - comp_for ::= expr _for designator comp_iter JUMP_BACK - ''' - - 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 - ''' - - def p_dictcomp(self, args): - ''' - 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 - - ''' - - def p_augmented_assign(self, args): - ''' - stmt ::= augassign1 - stmt ::= augassign2 - augassign1 ::= expr expr inplace_op designator - augassign1 ::= expr expr inplace_op ROT_THREE STORE_SUBSCR - augassign1 ::= expr expr inplace_op ROT_TWO STORE_SLICE+0 - augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+1 - augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+2 - augassign1 ::= expr expr inplace_op ROT_FOUR STORE_SLICE+3 - augassign2 ::= expr DUP_TOP LOAD_ATTR expr - inplace_op ROT_TWO STORE_ATTR - - inplace_op ::= INPLACE_ADD - inplace_op ::= INPLACE_SUBTRACT - inplace_op ::= INPLACE_MULTIPLY - inplace_op ::= INPLACE_DIVIDE - inplace_op ::= INPLACE_TRUE_DIVIDE - inplace_op ::= INPLACE_FLOOR_DIVIDE - inplace_op ::= INPLACE_MODULO - inplace_op ::= INPLACE_POWER - inplace_op ::= INPLACE_LSHIFT - inplace_op ::= INPLACE_RSHIFT - inplace_op ::= INPLACE_AND - inplace_op ::= INPLACE_XOR - inplace_op ::= INPLACE_OR - ''' - - def p_assign(self, args): - ''' - stmt ::= assign - assign ::= expr DUP_TOP designList - assign ::= expr designator - - stmt ::= assign2 - stmt ::= assign3 - assign2 ::= expr expr ROT_TWO designator designator - assign3 ::= expr expr expr ROT_THREE ROT_TWO designator designator designator - ''' - - def p_print(self, args): - ''' - 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 ::= print_items print_item - print_items ::= print_item - print_item ::= expr PRINT_ITEM_CONT - print_nl ::= PRINT_NEWLINE - ''' - - def p_print_to(self, args): - ''' - stmt ::= print_to - stmt ::= print_to_nl - stmt ::= print_nl_to - print_to ::= expr print_to_items POP_TOP - print_to_nl ::= expr print_to_items PRINT_NEWLINE_TO - print_nl_to ::= expr PRINT_NEWLINE_TO - print_to_items ::= print_to_items print_to_item - print_to_items ::= print_to_item - print_to_item ::= DUP_TOP expr ROT_TWO PRINT_ITEM_TO - ''' - - def p_import20(self, args): - ''' - stmt ::= importstmt - stmt ::= importfrom - stmt ::= importstar - stmt ::= importmultiple - - importlist2 ::= importlist2 import_as - importlist2 ::= import_as - import_as ::= IMPORT_NAME designator - 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 - importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist2 POP_TOP - 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 - ''' - - def p_grammar(self, args): - ''' - stmts ::= stmts sstmt - stmts ::= sstmt - sstmt ::= stmt - sstmt ::= ifelsestmtr - sstmt ::= return_stmt RETURN_LAST - - stmts_opt ::= stmts - stmts_opt ::= passstmt - passstmt ::= - - _stmts ::= _stmts stmt - _stmts ::= stmt - - c_stmts ::= _stmts - c_stmts ::= _stmts lastc_stmt - c_stmts ::= lastc_stmt - c_stmts ::= continue_stmts - - lastc_stmt ::= iflaststmt - lastc_stmt ::= whileelselaststmt - lastc_stmt ::= forelselaststmt - lastc_stmt ::= ifelsestmtr - lastc_stmt ::= ifelsestmtc - lastc_stmt ::= tryelsestmtc - - 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 - else_suitec ::= return_stmts - - designList ::= designator designator - designList ::= designator DUP_TOP designList - - designator ::= STORE_FAST - designator ::= STORE_NAME - designator ::= STORE_GLOBAL - designator ::= STORE_DEREF - designator ::= expr STORE_ATTR - designator ::= expr STORE_SLICE+0 - designator ::= expr expr STORE_SLICE+1 - designator ::= expr expr STORE_SLICE+2 - designator ::= expr expr expr STORE_SLICE+3 - designator ::= store_subscr - store_subscr ::= expr expr STORE_SUBSCR - designator ::= unpack - designator ::= unpack_list - - stmt ::= classdef - stmt ::= call_stmt - call_stmt ::= expr POP_TOP - - stmt ::= return_stmt - 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 - stmt ::= raise_stmt3 - - raise_stmt0 ::= RAISE_VARARGS_0 - 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 - stmt ::= whileelsestmt - stmt ::= while1elsestmt - stmt ::= forstmt - stmt ::= forelsestmt - stmt ::= trystmt - stmt ::= tryelsestmt - stmt ::= tryfinallystmt - stmt ::= withstmt - stmt ::= withasstmt - - stmt ::= del_stmt - del_stmt ::= DELETE_FAST - del_stmt ::= DELETE_NAME - del_stmt ::= DELETE_GLOBAL - del_stmt ::= expr DELETE_SLICE+0 - del_stmt ::= expr expr DELETE_SLICE+1 - del_stmt ::= expr expr DELETE_SLICE+2 - del_stmt ::= expr expr expr DELETE_SLICE+3 - 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 - classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1 - classdefdeco2 ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS - - _jump ::= JUMP_ABSOLUTE - _jump ::= JUMP_FORWARD - _jump ::= JUMP_BACK - - jmp_false ::= POP_JUMP_IF_FALSE - 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 - assert_expr_or ::= assert_expr jmp_true expr - 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 - - ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec - - 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 - - tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - try_middle else_suite COME_FROM - - tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - try_middle else_suitec COME_FROM - - tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - try_middle else_suitel COME_FROM - - try_middle ::= jmp_abs COME_FROM except_stmts - 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 - - except_suite ::= c_stmts_opt JUMP_FORWARD - except_suite ::= c_stmts_opt jmp_abs - except_suite ::= return_stmts - - except_cond1 ::= DUP_TOP expr COMPARE_OP - 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 - - withasstmt ::= expr SETUP_WITH designator suite_stmts_opt - POP_BLOCK LOAD_CONST COME_FROM - WITH_CLEANUP END_FINALLY - - whilestmt ::= SETUP_LOOP - testexpr - l_stmts_opt JUMP_BACK - POP_BLOCK COME_FROM - - whilestmt ::= SETUP_LOOP - testexpr - return_stmts - POP_BLOCK COME_FROM - - while1stmt ::= SETUP_LOOP l_stmts JUMP_BACK COME_FROM - while1stmt ::= SETUP_LOOP return_stmts COME_FROM - while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suite COME_FROM - - whileelsestmt ::= SETUP_LOOP testexpr - l_stmts_opt JUMP_BACK - POP_BLOCK - else_suite COME_FROM - - whileelselaststmt ::= SETUP_LOOP testexpr - l_stmts_opt JUMP_BACK - POP_BLOCK - else_suitec COME_FROM - - _for ::= GET_ITER FOR_ITER - _for ::= LOAD_CONST FOR_LOOP - - 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 - - forelsestmt ::= SETUP_LOOP expr _for designator - for_block POP_BLOCK else_suite COME_FROM - - forelselaststmt ::= SETUP_LOOP expr _for designator - for_block POP_BLOCK else_suitec COME_FROM - - forelselaststmtl ::= SETUP_LOOP expr _for designator - for_block POP_BLOCK else_suitel COME_FROM - - ''' - - def p_expr(self, args): - ''' - expr ::= _mklambda - expr ::= SET_LINENO - expr ::= LOAD_FAST - expr ::= LOAD_NAME - expr ::= LOAD_CONST - expr ::= LOAD_ASSERT - expr ::= LOAD_GLOBAL - expr ::= LOAD_DEREF - expr ::= LOAD_LOCALS - expr ::= load_attr - expr ::= binary_expr - expr ::= binary_expr_na - expr ::= build_list - expr ::= cmp - expr ::= mapexpr - expr ::= and - expr ::= and2 - expr ::= or - expr ::= unary_expr - expr ::= call_function - expr ::= unary_not - expr ::= unary_convert - expr ::= binary_subscr - expr ::= binary_subscr2 - expr ::= load_attr - expr ::= get_iter - expr ::= slice0 - expr ::= slice1 - expr ::= slice2 - expr ::= slice3 - expr ::= buildslice2 - expr ::= buildslice3 - expr ::= yield - - binary_expr ::= expr expr binary_op - binary_op ::= BINARY_ADD - binary_op ::= BINARY_MULTIPLY - binary_op ::= BINARY_AND - binary_op ::= BINARY_OR - binary_op ::= BINARY_XOR - binary_op ::= BINARY_SUBTRACT - binary_op ::= BINARY_DIVIDE - binary_op ::= BINARY_TRUE_DIVIDE - binary_op ::= BINARY_FLOOR_DIVIDE - binary_op ::= BINARY_MODULO - binary_op ::= BINARY_LSHIFT - binary_op ::= BINARY_RSHIFT - binary_op ::= BINARY_POWER - - unary_expr ::= expr unary_op - unary_op ::= UNARY_POSITIVE - unary_op ::= UNARY_NEGATIVE - unary_op ::= UNARY_INVERT - - unary_not ::= expr UNARY_NOT - unary_convert ::= expr UNARY_CONVERT - - binary_subscr ::= expr expr BINARY_SUBSCR - binary_subscr2 ::= expr expr DUP_TOPX_2 BINARY_SUBSCR - - load_attr ::= expr LOAD_ATTR - get_iter ::= expr GET_ITER - slice0 ::= expr SLICE+0 - slice0 ::= expr DUP_TOP SLICE+0 - slice1 ::= expr expr SLICE+1 - slice1 ::= expr expr DUP_TOPX_2 SLICE+1 - slice2 ::= expr expr SLICE+2 - slice2 ::= expr expr DUP_TOPX_2 SLICE+2 - slice3 ::= expr expr expr SLICE+3 - 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 - _mklambda ::= mklambda - - or ::= expr jmp_true expr _come_from - or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM - 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 - - ret_and ::= expr jmp_false ret_expr_or_cond COME_FROM - ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM - ret_cond ::= expr jmp_false expr RETURN_END_IF ret_expr_or_cond - ret_cond_not ::= expr jmp_true expr RETURN_END_IF ret_expr_or_cond - - 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 - - cmp ::= cmp_list - cmp ::= compare - compare ::= expr expr COMPARE_OP - cmp_list ::= expr cmp_list1 ROT_TWO POP_TOP - _come_from - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list1 COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP jmp_false - cmp_list1 _come_from - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP JUMP_IF_FALSE_OR_POP - cmp_list2 COME_FROM - cmp_list1 ::= expr DUP_TOP ROT_THREE - COMPARE_OP jmp_false - cmp_list2 _come_from - cmp_list2 ::= expr COMPARE_OP JUMP_FORWARD - cmp_list2 ::= expr COMPARE_OP RETURN_VALUE - mapexpr ::= BUILD_MAP kvlist - - kvlist ::= kvlist kv - kvlist ::= kvlist kv2 - kvlist ::= kvlist kv3 - kvlist ::= - - kv ::= DUP_TOP expr ROT_TWO expr STORE_SUBSCR - kv2 ::= DUP_TOP expr expr ROT_THREE STORE_SUBSCR - kv3 ::= expr expr STORE_MAP - - exprlist ::= exprlist expr - exprlist ::= expr - - nullexprlist ::= - ''' - def nonterminal(self, nt, args): collect = ('stmts', 'exprlist', 'kvlist', '_stmts', 'print_items') @@ -717,11 +96,7 @@ class Parser(GenericASTBuilder): # print >> sys.stderr, 'resolve', str(list) return GenericASTBuilder.resolve(self, list) -nop = lambda self, args: None - -p = Parser() - -def parse(tokens, customize): +def parse(p, tokens, customize): ''' Special handling for opcodes that take a variable number of arguments -- we add a new rule for each: @@ -738,7 +113,8 @@ def parse(tokens, customize): expr ::= expr {expr}^n CALL_FUNCTION_VAR_KW_n POP_TOP expr ::= expr {expr}^n CALL_FUNCTION_KW_n POP_TOP ''' - global p + nop = lambda self, args: None + for k, v in list(customize.items()): # avoid adding the same rule twice to this parser if k in p.customized: @@ -789,22 +165,35 @@ def parse(tokens, customize): return ast -def parser(version, co, out=sys.stdout, showasm=False): +def get_python_parser(version): + """ + Returns parser object for Python version 2 or 3 + depending on the parameter passed. + """ + if version < 3.0: + import uncompyle6.parsers.parse2 as parse2 + return parse2.Python2Parser() + else: + import uncompyle6.parsers.parse3 as parse3 + return parse3.Python3Parser() + +def python_parser(version, co, out=sys.stdout, showasm=False): import inspect assert inspect.iscode(co) from uncompyle6.scanner import get_scanner scanner = get_scanner(version) tokens, customize = scanner.disassemble(co) - if showasm: - for t in tokens: - print(t) + # if showasm: + # for t in tokens: + # print(t) - return parse(tokens, customize) + p = get_python_parser(version) + return parse(p, tokens, customize) if __name__ == '__main__': def parse_test(co): sys_version = sys.version_info.major + (sys.version_info.minor / 10.0) - ast = parser(sys_version, co, showasm=True) + ast = python_parser(sys_version, co, showasm=True) print(ast) return parse_test(parse_test.__code__) diff --git a/uncompyle6/parsers/__init__.py b/uncompyle6/parsers/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py new file mode 100644 index 00000000..899e9607 --- /dev/null +++ b/uncompyle6/parsers/parse2.py @@ -0,0 +1,646 @@ +# Copyright (c) 1999 John Aycock +# Copyright (c) 2000-2002 by hartmut Goebel +# Copyright (c) 2005 by Dan Pascu +# Copyright (c) 2015 Rocky Bernstein +# +# See main module for license. +""" +A spark grammar for Python 2.x. + +However instead of terminal symbols being the usual ASCII text, +e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens, +e.g. "LOAD_CONST 5", "STORE NAME myvariable", "SETUP_LOOP", etc. + +If we succeed in creating a parse tree, then we have a Python program +that a later phase can tern into a sequence of ASCII text. +""" + +from __future__ import print_function + +from uncompyle6.parser import PythonParser, AST +from uncompyle6.parsers.spark import GenericASTBuilder + +class Python2Parser(PythonParser): + + def __init__(self): + GenericASTBuilder.__init__(self, AST, 'stmts') + self.customized = {} + + def p_funcdef(self, args): + ''' + stmt ::= funcdef + funcdef ::= mkfunc designator + stmt ::= funcdefdeco + funcdefdeco ::= mkfuncdeco designator + mkfuncdeco ::= expr mkfuncdeco CALL_FUNCTION_1 + mkfuncdeco ::= expr mkfuncdeco0 CALL_FUNCTION_1 + mkfuncdeco0 ::= mkfunc + load_closure ::= load_closure LOAD_CLOSURE + load_closure ::= LOAD_CLOSURE + ''' + + def p_list_comprehension(self, args): + ''' + expr ::= list_compr + list_compr ::= BUILD_LIST_0 list_iter + + list_iter ::= list_for + list_iter ::= list_if + list_iter ::= list_if_not + list_iter ::= lc_body + + _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 + + 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 + comp_iter ::= comp_body + comp_body ::= set_comp_body + comp_body ::= gen_comp_body + comp_body ::= dict_comp_body + set_comp_body ::= expr SET_ADD + gen_comp_body ::= expr YIELD_VALUE POP_TOP + dict_comp_body ::= expr expr MAP_ADD + + comp_if ::= expr jmp_false comp_iter + comp_ifnot ::= expr jmp_true comp_iter + comp_for ::= expr _for designator comp_iter JUMP_BACK + ''' + + 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 + ''' + + def p_dictcomp(self, args): + ''' + 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 + + ''' + + def p_augmented_assign(self, args): + ''' + stmt ::= augassign1 + stmt ::= augassign2 + augassign1 ::= expr expr inplace_op designator + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SUBSCR + augassign1 ::= expr expr inplace_op ROT_TWO STORE_SLICE+0 + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+1 + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+2 + augassign1 ::= expr expr inplace_op ROT_FOUR STORE_SLICE+3 + augassign2 ::= expr DUP_TOP LOAD_ATTR expr + inplace_op ROT_TWO STORE_ATTR + + inplace_op ::= INPLACE_ADD + inplace_op ::= INPLACE_SUBTRACT + inplace_op ::= INPLACE_MULTIPLY + inplace_op ::= INPLACE_DIVIDE + inplace_op ::= INPLACE_TRUE_DIVIDE + inplace_op ::= INPLACE_FLOOR_DIVIDE + inplace_op ::= INPLACE_MODULO + inplace_op ::= INPLACE_POWER + inplace_op ::= INPLACE_LSHIFT + inplace_op ::= INPLACE_RSHIFT + inplace_op ::= INPLACE_AND + inplace_op ::= INPLACE_XOR + inplace_op ::= INPLACE_OR + ''' + + def p_assign(self, args): + ''' + stmt ::= assign + assign ::= expr DUP_TOP designList + assign ::= expr designator + + stmt ::= assign2 + stmt ::= assign3 + assign2 ::= expr expr ROT_TWO designator designator + assign3 ::= expr expr expr ROT_THREE ROT_TWO designator designator designator + ''' + + def p_print(self, args): + ''' + 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 ::= print_items print_item + print_items ::= print_item + print_item ::= expr PRINT_ITEM_CONT + print_nl ::= PRINT_NEWLINE + ''' + + def p_print_to(self, args): + ''' + stmt ::= print_to + stmt ::= print_to_nl + stmt ::= print_nl_to + print_to ::= expr print_to_items POP_TOP + print_to_nl ::= expr print_to_items PRINT_NEWLINE_TO + print_nl_to ::= expr PRINT_NEWLINE_TO + print_to_items ::= print_to_items print_to_item + print_to_items ::= print_to_item + print_to_item ::= DUP_TOP expr ROT_TWO PRINT_ITEM_TO + ''' + + def p_import20(self, args): + ''' + stmt ::= importstmt + stmt ::= importfrom + stmt ::= importstar + stmt ::= importmultiple + + importlist2 ::= importlist2 import_as + importlist2 ::= import_as + import_as ::= IMPORT_NAME designator + 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 + importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist2 POP_TOP + 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 + ''' + + def p_grammar(self, args): + ''' + stmts ::= stmts sstmt + stmts ::= sstmt + sstmt ::= stmt + sstmt ::= ifelsestmtr + sstmt ::= return_stmt RETURN_LAST + + stmts_opt ::= stmts + stmts_opt ::= passstmt + passstmt ::= + + _stmts ::= _stmts stmt + _stmts ::= stmt + + c_stmts ::= _stmts + c_stmts ::= _stmts lastc_stmt + c_stmts ::= lastc_stmt + c_stmts ::= continue_stmts + + lastc_stmt ::= iflaststmt + lastc_stmt ::= whileelselaststmt + lastc_stmt ::= forelselaststmt + lastc_stmt ::= ifelsestmtr + lastc_stmt ::= ifelsestmtc + lastc_stmt ::= tryelsestmtc + + 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 + else_suitec ::= return_stmts + + designList ::= designator designator + designList ::= designator DUP_TOP designList + + designator ::= STORE_FAST + designator ::= STORE_NAME + designator ::= STORE_GLOBAL + designator ::= STORE_DEREF + designator ::= expr STORE_ATTR + designator ::= expr STORE_SLICE+0 + designator ::= expr expr STORE_SLICE+1 + designator ::= expr expr STORE_SLICE+2 + designator ::= expr expr expr STORE_SLICE+3 + designator ::= store_subscr + store_subscr ::= expr expr STORE_SUBSCR + designator ::= unpack + designator ::= unpack_list + + stmt ::= classdef + stmt ::= call_stmt + call_stmt ::= expr POP_TOP + + stmt ::= return_stmt + 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 + stmt ::= raise_stmt3 + + raise_stmt0 ::= RAISE_VARARGS_0 + 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 + stmt ::= whileelsestmt + stmt ::= while1elsestmt + stmt ::= forstmt + stmt ::= forelsestmt + stmt ::= trystmt + stmt ::= tryelsestmt + stmt ::= tryfinallystmt + stmt ::= withstmt + stmt ::= withasstmt + + stmt ::= del_stmt + del_stmt ::= DELETE_FAST + del_stmt ::= DELETE_NAME + del_stmt ::= DELETE_GLOBAL + del_stmt ::= expr DELETE_SLICE+0 + del_stmt ::= expr expr DELETE_SLICE+1 + del_stmt ::= expr expr DELETE_SLICE+2 + del_stmt ::= expr expr expr DELETE_SLICE+3 + 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 + classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1 + classdefdeco2 ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS + + _jump ::= JUMP_ABSOLUTE + _jump ::= JUMP_FORWARD + _jump ::= JUMP_BACK + + jmp_false ::= POP_JUMP_IF_FALSE + 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 + assert_expr_or ::= assert_expr jmp_true expr + 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 + + ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec + + 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 + + tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suite COME_FROM + + tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suitec COME_FROM + + tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suitel COME_FROM + + try_middle ::= jmp_abs COME_FROM except_stmts + 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 + + except_suite ::= c_stmts_opt JUMP_FORWARD + except_suite ::= c_stmts_opt jmp_abs + except_suite ::= return_stmts + + except_cond1 ::= DUP_TOP expr COMPARE_OP + 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 + + withasstmt ::= expr SETUP_WITH designator suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM + WITH_CLEANUP END_FINALLY + + whilestmt ::= SETUP_LOOP + testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK COME_FROM + + whilestmt ::= SETUP_LOOP + testexpr + return_stmts + POP_BLOCK COME_FROM + + while1stmt ::= SETUP_LOOP l_stmts JUMP_BACK COME_FROM + while1stmt ::= SETUP_LOOP return_stmts COME_FROM + while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suite COME_FROM + + whileelsestmt ::= SETUP_LOOP testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK + else_suite COME_FROM + + whileelselaststmt ::= SETUP_LOOP testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK + else_suitec COME_FROM + + _for ::= GET_ITER FOR_ITER + _for ::= LOAD_CONST FOR_LOOP + + 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 + + forelsestmt ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suite COME_FROM + + forelselaststmt ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suitec COME_FROM + + forelselaststmtl ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suitel COME_FROM + + ''' + + def p_expr(self, args): + ''' + expr ::= _mklambda + expr ::= SET_LINENO + expr ::= LOAD_FAST + expr ::= LOAD_NAME + expr ::= LOAD_CONST + expr ::= LOAD_ASSERT + expr ::= LOAD_GLOBAL + expr ::= LOAD_DEREF + expr ::= LOAD_LOCALS + expr ::= load_attr + expr ::= binary_expr + expr ::= binary_expr_na + expr ::= build_list + expr ::= cmp + expr ::= mapexpr + expr ::= and + expr ::= and2 + expr ::= or + expr ::= unary_expr + expr ::= call_function + expr ::= unary_not + expr ::= unary_convert + expr ::= binary_subscr + expr ::= binary_subscr2 + expr ::= load_attr + expr ::= get_iter + expr ::= slice0 + expr ::= slice1 + expr ::= slice2 + expr ::= slice3 + expr ::= buildslice2 + expr ::= buildslice3 + expr ::= yield + + binary_expr ::= expr expr binary_op + binary_op ::= BINARY_ADD + binary_op ::= BINARY_MULTIPLY + binary_op ::= BINARY_AND + binary_op ::= BINARY_OR + binary_op ::= BINARY_XOR + binary_op ::= BINARY_SUBTRACT + binary_op ::= BINARY_DIVIDE + binary_op ::= BINARY_TRUE_DIVIDE + binary_op ::= BINARY_FLOOR_DIVIDE + binary_op ::= BINARY_MODULO + binary_op ::= BINARY_LSHIFT + binary_op ::= BINARY_RSHIFT + binary_op ::= BINARY_POWER + + unary_expr ::= expr unary_op + unary_op ::= UNARY_POSITIVE + unary_op ::= UNARY_NEGATIVE + unary_op ::= UNARY_INVERT + + unary_not ::= expr UNARY_NOT + unary_convert ::= expr UNARY_CONVERT + + binary_subscr ::= expr expr BINARY_SUBSCR + binary_subscr2 ::= expr expr DUP_TOPX_2 BINARY_SUBSCR + + load_attr ::= expr LOAD_ATTR + get_iter ::= expr GET_ITER + slice0 ::= expr SLICE+0 + slice0 ::= expr DUP_TOP SLICE+0 + slice1 ::= expr expr SLICE+1 + slice1 ::= expr expr DUP_TOPX_2 SLICE+1 + slice2 ::= expr expr SLICE+2 + slice2 ::= expr expr DUP_TOPX_2 SLICE+2 + slice3 ::= expr expr expr SLICE+3 + 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 + _mklambda ::= mklambda + + or ::= expr jmp_true expr _come_from + or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM + 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 + + ret_and ::= expr jmp_false ret_expr_or_cond COME_FROM + ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM + ret_cond ::= expr jmp_false expr RETURN_END_IF ret_expr_or_cond + ret_cond_not ::= expr jmp_true expr RETURN_END_IF ret_expr_or_cond + + 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 + + cmp ::= cmp_list + cmp ::= compare + compare ::= expr expr COMPARE_OP + cmp_list ::= expr cmp_list1 ROT_TWO POP_TOP + _come_from + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP JUMP_IF_FALSE_OR_POP + cmp_list1 COME_FROM + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP jmp_false + cmp_list1 _come_from + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP JUMP_IF_FALSE_OR_POP + cmp_list2 COME_FROM + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP jmp_false + cmp_list2 _come_from + cmp_list2 ::= expr COMPARE_OP JUMP_FORWARD + cmp_list2 ::= expr COMPARE_OP RETURN_VALUE + mapexpr ::= BUILD_MAP kvlist + + kvlist ::= kvlist kv + kvlist ::= kvlist kv2 + kvlist ::= kvlist kv3 + kvlist ::= + + kv ::= DUP_TOP expr ROT_TWO expr STORE_SUBSCR + kv2 ::= DUP_TOP expr expr ROT_THREE STORE_SUBSCR + kv3 ::= expr expr STORE_MAP + + exprlist ::= exprlist expr + exprlist ::= expr + + nullexprlist ::= + ''' diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py new file mode 100644 index 00000000..ba894bdd --- /dev/null +++ b/uncompyle6/parsers/parse3.py @@ -0,0 +1,646 @@ +# Copyright (c) 1999 John Aycock +# Copyright (c) 2000-2002 by hartmut Goebel +# Copyright (c) 2005 by Dan Pascu +# Copyright (c) 2015 Rocky Bernstein +# +# See main module for license. +""" +A spark grammar for Python 3.x. + +However instead of terminal symbols being the usual ASCII text, +e.g. 5, myvariable, "for", etc. they are CPython Bytecode tokens, +e.g. "LOAD_CONST 5", "STORE NAME myvariable", "SETUP_LOOP", etc. + +If we succeed in creating a parse tree, then we have a Python program +that a later phase can tern into a sequence of ASCII text. +""" + +from __future__ import print_function + +from uncompyle6.parser import PythonParser, AST +from uncompyle6.parsers.spark import GenericASTBuilder + +class Python3Parser(PythonParser): + + def __init__(self): + GenericASTBuilder.__init__(self, AST, 'stmts') + self.customized = {} + + def p_funcdef(self, args): + ''' + stmt ::= funcdef + funcdef ::= mkfunc designator + stmt ::= funcdefdeco + funcdefdeco ::= mkfuncdeco designator + mkfuncdeco ::= expr mkfuncdeco CALL_FUNCTION_1 + mkfuncdeco ::= expr mkfuncdeco0 CALL_FUNCTION_1 + mkfuncdeco0 ::= mkfunc + load_closure ::= load_closure LOAD_CLOSURE + load_closure ::= LOAD_CLOSURE + ''' + + def p_list_comprehension(self, args): + ''' + expr ::= list_compr + list_compr ::= BUILD_LIST_0 list_iter + + list_iter ::= list_for + list_iter ::= list_if + list_iter ::= list_if_not + list_iter ::= lc_body + + _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 + + 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 + comp_iter ::= comp_body + comp_body ::= set_comp_body + comp_body ::= gen_comp_body + comp_body ::= dict_comp_body + set_comp_body ::= expr SET_ADD + gen_comp_body ::= expr YIELD_VALUE POP_TOP + dict_comp_body ::= expr expr MAP_ADD + + comp_if ::= expr jmp_false comp_iter + comp_ifnot ::= expr jmp_true comp_iter + comp_for ::= expr _for designator comp_iter JUMP_BACK + ''' + + 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 + ''' + + def p_dictcomp(self, args): + ''' + 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 + + ''' + + def p_augmented_assign(self, args): + ''' + stmt ::= augassign1 + stmt ::= augassign2 + augassign1 ::= expr expr inplace_op designator + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SUBSCR + augassign1 ::= expr expr inplace_op ROT_TWO STORE_SLICE+0 + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+1 + augassign1 ::= expr expr inplace_op ROT_THREE STORE_SLICE+2 + augassign1 ::= expr expr inplace_op ROT_FOUR STORE_SLICE+3 + augassign2 ::= expr DUP_TOP LOAD_ATTR expr + inplace_op ROT_TWO STORE_ATTR + + inplace_op ::= INPLACE_ADD + inplace_op ::= INPLACE_SUBTRACT + inplace_op ::= INPLACE_MULTIPLY + inplace_op ::= INPLACE_DIVIDE + inplace_op ::= INPLACE_TRUE_DIVIDE + inplace_op ::= INPLACE_FLOOR_DIVIDE + inplace_op ::= INPLACE_MODULO + inplace_op ::= INPLACE_POWER + inplace_op ::= INPLACE_LSHIFT + inplace_op ::= INPLACE_RSHIFT + inplace_op ::= INPLACE_AND + inplace_op ::= INPLACE_XOR + inplace_op ::= INPLACE_OR + ''' + + def p_assign(self, args): + ''' + stmt ::= assign + assign ::= expr DUP_TOP designList + assign ::= expr designator + + stmt ::= assign2 + stmt ::= assign3 + assign2 ::= expr expr ROT_TWO designator designator + assign3 ::= expr expr expr ROT_THREE ROT_TWO designator designator designator + ''' + + def p_print(self, args): + ''' + 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 ::= print_items print_item + print_items ::= print_item + print_item ::= expr PRINT_ITEM_CONT + print_nl ::= PRINT_NEWLINE + ''' + + def p_print_to(self, args): + ''' + stmt ::= print_to + stmt ::= print_to_nl + stmt ::= print_nl_to + print_to ::= expr print_to_items POP_TOP + print_to_nl ::= expr print_to_items PRINT_NEWLINE_TO + print_nl_to ::= expr PRINT_NEWLINE_TO + print_to_items ::= print_to_items print_to_item + print_to_items ::= print_to_item + print_to_item ::= DUP_TOP expr ROT_TWO PRINT_ITEM_TO + ''' + + def p_import20(self, args): + ''' + stmt ::= importstmt + stmt ::= importfrom + stmt ::= importstar + stmt ::= importmultiple + + importlist2 ::= importlist2 import_as + importlist2 ::= import_as + import_as ::= IMPORT_NAME designator + 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 + importfrom ::= LOAD_CONST LOAD_CONST IMPORT_NAME importlist2 POP_TOP + 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 + ''' + + def p_grammar(self, args): + ''' + stmts ::= stmts sstmt + stmts ::= sstmt + sstmt ::= stmt + sstmt ::= ifelsestmtr + sstmt ::= return_stmt RETURN_LAST + + stmts_opt ::= stmts + stmts_opt ::= passstmt + passstmt ::= + + _stmts ::= _stmts stmt + _stmts ::= stmt + + c_stmts ::= _stmts + c_stmts ::= _stmts lastc_stmt + c_stmts ::= lastc_stmt + c_stmts ::= continue_stmts + + lastc_stmt ::= iflaststmt + lastc_stmt ::= whileelselaststmt + lastc_stmt ::= forelselaststmt + lastc_stmt ::= ifelsestmtr + lastc_stmt ::= ifelsestmtc + lastc_stmt ::= tryelsestmtc + + 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 + else_suitec ::= return_stmts + + designList ::= designator designator + designList ::= designator DUP_TOP designList + + designator ::= STORE_FAST + designator ::= STORE_NAME + designator ::= STORE_GLOBAL + designator ::= STORE_DEREF + designator ::= expr STORE_ATTR + designator ::= expr STORE_SLICE+0 + designator ::= expr expr STORE_SLICE+1 + designator ::= expr expr STORE_SLICE+2 + designator ::= expr expr expr STORE_SLICE+3 + designator ::= store_subscr + store_subscr ::= expr expr STORE_SUBSCR + designator ::= unpack + designator ::= unpack_list + + stmt ::= classdef + stmt ::= call_stmt + call_stmt ::= expr POP_TOP + + stmt ::= return_stmt + 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 + stmt ::= raise_stmt3 + + raise_stmt0 ::= RAISE_VARARGS_0 + 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 + stmt ::= whileelsestmt + stmt ::= while1elsestmt + stmt ::= forstmt + stmt ::= forelsestmt + stmt ::= trystmt + stmt ::= tryelsestmt + stmt ::= tryfinallystmt + stmt ::= withstmt + stmt ::= withasstmt + + stmt ::= del_stmt + del_stmt ::= DELETE_FAST + del_stmt ::= DELETE_NAME + del_stmt ::= DELETE_GLOBAL + del_stmt ::= expr DELETE_SLICE+0 + del_stmt ::= expr expr DELETE_SLICE+1 + del_stmt ::= expr expr DELETE_SLICE+2 + del_stmt ::= expr expr expr DELETE_SLICE+3 + 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 + classdefdeco1 ::= expr classdefdeco2 CALL_FUNCTION_1 + classdefdeco2 ::= LOAD_CONST expr mkfunc CALL_FUNCTION_0 BUILD_CLASS + + _jump ::= JUMP_ABSOLUTE + _jump ::= JUMP_FORWARD + _jump ::= JUMP_BACK + + jmp_false ::= POP_JUMP_IF_FALSE + 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 + assert_expr_or ::= assert_expr jmp_true expr + 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 + + ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec + + 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 + + tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suite COME_FROM + + tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suitec COME_FROM + + tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + try_middle else_suitel COME_FROM + + try_middle ::= jmp_abs COME_FROM except_stmts + 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 + + except_suite ::= c_stmts_opt JUMP_FORWARD + except_suite ::= c_stmts_opt jmp_abs + except_suite ::= return_stmts + + except_cond1 ::= DUP_TOP expr COMPARE_OP + 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 + + withasstmt ::= expr SETUP_WITH designator suite_stmts_opt + POP_BLOCK LOAD_CONST COME_FROM + WITH_CLEANUP END_FINALLY + + whilestmt ::= SETUP_LOOP + testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK COME_FROM + + whilestmt ::= SETUP_LOOP + testexpr + return_stmts + POP_BLOCK COME_FROM + + while1stmt ::= SETUP_LOOP l_stmts JUMP_BACK COME_FROM + while1stmt ::= SETUP_LOOP return_stmts COME_FROM + while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK else_suite COME_FROM + + whileelsestmt ::= SETUP_LOOP testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK + else_suite COME_FROM + + whileelselaststmt ::= SETUP_LOOP testexpr + l_stmts_opt JUMP_BACK + POP_BLOCK + else_suitec COME_FROM + + _for ::= GET_ITER FOR_ITER + _for ::= LOAD_CONST FOR_LOOP + + 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 + + forelsestmt ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suite COME_FROM + + forelselaststmt ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suitec COME_FROM + + forelselaststmtl ::= SETUP_LOOP expr _for designator + for_block POP_BLOCK else_suitel COME_FROM + + ''' + + def p_expr(self, args): + ''' + expr ::= _mklambda + expr ::= SET_LINENO + expr ::= LOAD_FAST + expr ::= LOAD_NAME + expr ::= LOAD_CONST + expr ::= LOAD_ASSERT + expr ::= LOAD_GLOBAL + expr ::= LOAD_DEREF + expr ::= LOAD_LOCALS + expr ::= load_attr + expr ::= binary_expr + expr ::= binary_expr_na + expr ::= build_list + expr ::= cmp + expr ::= mapexpr + expr ::= and + expr ::= and2 + expr ::= or + expr ::= unary_expr + expr ::= call_function + expr ::= unary_not + expr ::= unary_convert + expr ::= binary_subscr + expr ::= binary_subscr2 + expr ::= load_attr + expr ::= get_iter + expr ::= slice0 + expr ::= slice1 + expr ::= slice2 + expr ::= slice3 + expr ::= buildslice2 + expr ::= buildslice3 + expr ::= yield + + binary_expr ::= expr expr binary_op + binary_op ::= BINARY_ADD + binary_op ::= BINARY_MULTIPLY + binary_op ::= BINARY_AND + binary_op ::= BINARY_OR + binary_op ::= BINARY_XOR + binary_op ::= BINARY_SUBTRACT + binary_op ::= BINARY_DIVIDE + binary_op ::= BINARY_TRUE_DIVIDE + binary_op ::= BINARY_FLOOR_DIVIDE + binary_op ::= BINARY_MODULO + binary_op ::= BINARY_LSHIFT + binary_op ::= BINARY_RSHIFT + binary_op ::= BINARY_POWER + + unary_expr ::= expr unary_op + unary_op ::= UNARY_POSITIVE + unary_op ::= UNARY_NEGATIVE + unary_op ::= UNARY_INVERT + + unary_not ::= expr UNARY_NOT + unary_convert ::= expr UNARY_CONVERT + + binary_subscr ::= expr expr BINARY_SUBSCR + binary_subscr2 ::= expr expr DUP_TOPX_2 BINARY_SUBSCR + + load_attr ::= expr LOAD_ATTR + get_iter ::= expr GET_ITER + slice0 ::= expr SLICE+0 + slice0 ::= expr DUP_TOP SLICE+0 + slice1 ::= expr expr SLICE+1 + slice1 ::= expr expr DUP_TOPX_2 SLICE+1 + slice2 ::= expr expr SLICE+2 + slice2 ::= expr expr DUP_TOPX_2 SLICE+2 + slice3 ::= expr expr expr SLICE+3 + 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 + _mklambda ::= mklambda + + or ::= expr jmp_true expr _come_from + or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM + 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 + + ret_and ::= expr jmp_false ret_expr_or_cond COME_FROM + ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM + ret_cond ::= expr jmp_false expr RETURN_END_IF ret_expr_or_cond + ret_cond_not ::= expr jmp_true expr RETURN_END_IF ret_expr_or_cond + + 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 + + cmp ::= cmp_list + cmp ::= compare + compare ::= expr expr COMPARE_OP + cmp_list ::= expr cmp_list1 ROT_TWO POP_TOP + _come_from + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP JUMP_IF_FALSE_OR_POP + cmp_list1 COME_FROM + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP jmp_false + cmp_list1 _come_from + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP JUMP_IF_FALSE_OR_POP + cmp_list2 COME_FROM + cmp_list1 ::= expr DUP_TOP ROT_THREE + COMPARE_OP jmp_false + cmp_list2 _come_from + cmp_list2 ::= expr COMPARE_OP JUMP_FORWARD + cmp_list2 ::= expr COMPARE_OP RETURN_VALUE + mapexpr ::= BUILD_MAP kvlist + + kvlist ::= kvlist kv + kvlist ::= kvlist kv2 + kvlist ::= kvlist kv3 + kvlist ::= + + kv ::= DUP_TOP expr ROT_TWO expr STORE_SUBSCR + kv2 ::= DUP_TOP expr expr ROT_THREE STORE_SUBSCR + kv3 ::= expr expr STORE_MAP + + exprlist ::= exprlist expr + exprlist ::= expr + + nullexprlist ::= + ''' diff --git a/uncompyle6/spark.py b/uncompyle6/parsers/spark.py old mode 100755 new mode 100644 similarity index 99% rename from uncompyle6/spark.py rename to uncompyle6/parsers/spark.py index 829bc5c0..52956733 --- a/uncompyle6/spark.py +++ b/uncompyle6/parsers/spark.py @@ -1,4 +1,3 @@ -from __future__ import print_function ''' Copyright (c) 1998-2002 John Aycock @@ -22,7 +21,9 @@ Copyright (c) 1998-2002 John Aycock SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' -__version__ = 'SPARK-0.7 (pre-alpha-7) uncompyle trim' +from __future__ import print_function + +__version__ = 'SPARK-1.0 Python3 compatible' def _namelist(instance): namelist, namedict, classlist = [], {}, [instance.__class__] diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index cc553c7e..220091aa 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -104,8 +104,7 @@ class Scanner(object): self.opc = opcode_34 # FIXME: This weird Python2 behavior is not Python3 - if not PYTHON3: - return self.resetTokenClass() + self.resetTokenClass() def setShowAsm(self, showasm, out=None): self.showasm = showasm @@ -350,7 +349,8 @@ def get_scanner(version): if __name__ == "__main__": import inspect, uncompyle6 co = inspect.currentframe().f_code - tokens, customize = Scanner(uncompyle6.PYTHON_VERSION).disassemble(co) + scanner = get_scanner(uncompyle6.PYTHON_VERSION) + tokens, customize = scanner.disassemble(co) print('-' * 30) for t in tokens: print(t) diff --git a/uncompyle6/scanners/scanner25.py b/uncompyle6/scanners/scanner25.py index de79fe89..7cb17dfe 100644 --- a/uncompyle6/scanners/scanner25.py +++ b/uncompyle6/scanners/scanner25.py @@ -23,7 +23,7 @@ import uncompyle6.scanner as scan class Scanner25(scan.Scanner): def __init__(self): - self.Token = scan.Scanner.__init__(self, 2.5) + scan.Scanner.__init__(self, 2.5) # check def disassemble(self, co, classname=None): ''' diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index 48cee6cb..b87126b6 100644 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -23,7 +23,7 @@ import uncompyle6.scanner as scan class Scanner26(scan.Scanner): def __init__(self): - self.Token = scan.Scanner.__init__(self, 2.6) + scan.Scanner.__init__(self, 2.5) # check def disassemble(self, co, classname=None): ''' diff --git a/uncompyle6/scanners/scanner27.py b/uncompyle6/scanners/scanner27.py index 4f971656..d3c4c418 100644 --- a/uncompyle6/scanners/scanner27.py +++ b/uncompyle6/scanners/scanner27.py @@ -22,14 +22,14 @@ import uncompyle6.scanner as scan class Scanner27(scan.Scanner): def __init__(self): - self.Token = scan.Scanner.__init__(self, 2.7) # check + scan.Scanner.__init__(self, 2.7) # check def disassemble(self, co, classname=None): - ''' + """ Disassemble a code object, returning a list of 'Token'. The main part of this procedure is modelled after dis.disassemble(). - ''' + """ rv = [] customize = {} Token = self.Token # shortcut diff --git a/uncompyle6/scanners/scanner32.py b/uncompyle6/scanners/scanner32.py index e8d6b610..95eedf0f 100644 --- a/uncompyle6/scanners/scanner32.py +++ b/uncompyle6/scanners/scanner32.py @@ -28,7 +28,7 @@ import uncompyle6.scanner as scan class Scanner32(scan.Scanner): def __init__(self): - self.Token = scan.Scanner.__init__(self, 3.2) # check + scan.Scanner.__init__(self, 3.2) # check def run(self, bytecode): code_object = marshal.loads(bytecode) diff --git a/uncompyle6/scanners/scanner34.py b/uncompyle6/scanners/scanner34.py index b415f6c0..1e0e80f4 100644 --- a/uncompyle6/scanners/scanner34.py +++ b/uncompyle6/scanners/scanner34.py @@ -29,7 +29,7 @@ import uncompyle6.scanner as scan class Scanner34(scan.Scanner): def __init__(self): - self.Token = scan.Scanner.__init__(self, 3.4) # check + scan.Scanner.__init__(self, 3.4) # check def disassemble(self, co): fn = self.disassemble_built_in if PYTHON_VERSION == 3.4 \ diff --git a/uncompyle6/walker.py b/uncompyle6/walker.py index df0eba03..37dd9d4d 100644 --- a/uncompyle6/walker.py +++ b/uncompyle6/walker.py @@ -43,8 +43,9 @@ from __future__ import print_function import inspect, sys, re from uncompyle6 import PYTHON3 -from uncompyle6.spark import GenericASTTraversal -from uncompyle6.parser import AST +from uncompyle6.parser import AST, get_python_parser +from uncompyle6.parsers.spark import GenericASTTraversal +import uncompyle6.parser as python_parser from uncompyle6.scanner import Token, Code, get_scanner if PYTHON3: @@ -56,8 +57,6 @@ else: minint = -sys.maxint-1 maxint = sys.maxint -import uncompyle6.parser as dparser - # Some ASTs used for comparing code fragments (like 'return None' at # the end of functions). @@ -402,7 +401,7 @@ escape = re.compile(r''' ( [{] (?P [^}]* ) [}] )) ''', re.VERBOSE) -class ParserError(dparser.ParserError): +class ParserError(python_parser.ParserError): def __init__(self, error, tokens): self.error = error # previous exception self.tokens = tokens @@ -445,13 +444,14 @@ def find_none(node): class Walker(GenericASTTraversal, object): stacked_params = ('f', 'indent', 'isLambda', '_globals') - def __init__(self, out, scanner, showast=False): + def __init__(self, version, out, scanner, showast=False): GenericASTTraversal.__init__(self, ast=None) self.scanner = scanner params = { 'f': out, 'indent': '', } + self.p = get_python_parser(version) self.showast = showast self.params = params self.param_stack = [] @@ -1399,8 +1399,8 @@ class Walker(GenericASTTraversal, object): if isLambda: tokens.append(Token('LAMBDA_MARKER')) try: - ast = dparser.parse(tokens, customize) - except dparser.ParserError as e: + ast = python_parser.parse(self.p, tokens, customize) + except python_parser.ParserError as e: raise ParserError(e, tokens) if self.showast: self.print_(repr(ast)) @@ -1417,8 +1417,8 @@ class Walker(GenericASTTraversal, object): # Build AST from disassembly. try: - ast = dparser.parse(tokens, customize) - except dparser.ParserError as e: + ast = python_parser.parse(self.p, tokens, customize) + except python_parser.ParserError as e: raise ParserError(e, tokens) if self.showast: @@ -1438,7 +1438,7 @@ def walker(version, co, out=sys.stdout, showasm=False, showast=False): print(t) # Build AST from disassembly. - walk = Walker(out, scanner, showast=showast) + walk = Walker(version, out, scanner, showast=showast) try: walk.ast = walk.build_ast(tokens, customize)