diff --git a/.gitignore b/.gitignore index c51eeaab..59caeedf 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ build /.venv* /.idea /.hypothesis -./ChangeLog +ChangeLog diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 0b347477..c2e368d9 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -475,7 +475,6 @@ class PythonParser(GenericASTBuilder): expr ::= LOAD_CONST expr ::= LOAD_GLOBAL expr ::= LOAD_DEREF - expr ::= attribute expr ::= binary_expr expr ::= list expr ::= compare @@ -487,7 +486,6 @@ class PythonParser(GenericASTBuilder): expr ::= unary_not expr ::= subscript expr ::= subscript2 - expr ::= get_iter expr ::= yield binary_expr ::= expr expr binary_op diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index b79d8a36..0bf18607 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -255,8 +255,8 @@ class Python2Parser(PythonParser): # include instructions that don't need customization, # but we'll do a finer check after the rough breakout. customize_instruction_basenames = frozenset( - ('BUILD', 'CALL', 'CONTINUE', - 'DELETE', 'DUP', 'EXEC', 'JUMP', + ('BUILD', 'CALL', 'CONTINUE', 'DELETE', + 'DUP', 'EXEC', 'GET', 'JUMP', 'LOAD', 'LOOKUP', 'MAKE', 'SETUP', 'RAISE', 'UNPACK')) @@ -374,17 +374,24 @@ class Python2Parser(PythonParser): """, nop_func) custom_ops_seen.add(opname) continue + elif opname == 'GET_ITER': + self.addRule(""" + expr ::= get_iter + attribute ::= expr GET_ITER + """, nop_func) + custom_ops_seen.add(opname) + continue elif opname_base in ('DUP_TOPX', 'RAISE_VARARGS'): # FIXME: remove these conditions if they are not needed. # no longer need to add a rule continue elif opname == 'EXEC_STMT': self.addRule(""" - stmt ::= exec_stmt - exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT - exec_stmt ::= expr exprlist EXEC_STMT - exprlist ::= expr+ - """, nop_func) + stmt ::= exec_stmt + exec_stmt ::= expr exprlist DUP_TOP EXEC_STMT + exec_stmt ::= expr exprlist EXEC_STMT + exprlist ::= expr+ + """, nop_func) continue elif opname == 'JUMP_IF_NOT_DEBUG': v = token.attr @@ -400,6 +407,13 @@ class Python2Parser(PythonParser): RAISE_VARARGS_1 COME_FROM """, nop_func) continue + elif opname == 'LOAD_ATTR': + self.addRule(""" + expr ::= attribute + attribute ::= expr LOAD_ATTR + """, nop_func) + custom_ops_seen.add(opname) + continue elif opname == 'LOAD_LISTCOMP': self.addRule("expr ::= listcomp", nop_func) custom_ops_seen.add(opname) @@ -413,7 +427,11 @@ class Python2Parser(PythonParser): continue elif opname == 'LOOKUP_METHOD': # A PyPy speciality - DRY with parse3 - self.addRule("attribute ::= expr LOOKUP_METHOD", nop_func) + self.addRule(""" + expr ::= attribute + attribute ::= expr LOOKUP_METHOD + """, + nop_func) custom_ops_seen.add(opname) continue elif opname_base == 'MAKE_FUNCTION': diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index 79185197..eda9c053 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -562,7 +562,7 @@ class Python3Parser(PythonParser): # include instructions that don't need customization, # but we'll do a finer check after the rough breakout. customize_instruction_basenames = frozenset( - ('BUILD', 'CALL', 'CONTINUE', 'DELETE', + ('BUILD', 'CALL', 'CONTINUE', 'DELETE', 'GET', 'JUMP', 'LOAD', 'LOOKUP', 'MAKE', 'RAISE', 'UNPACK')) @@ -733,6 +733,9 @@ class Python3Parser(PythonParser): ('kwarg ' * args_kw) + 'expr ' * nak + opname) self.add_unique_rule(rule, opname, token.attr, customize) + elif opname == 'CONTINUE': + self.addRule('continue ::= CONTINUE', nop_func) + custom_ops_seen.add(opname) elif opname == 'CONTINUE_LOOP': self.addRule('continue ::= CONTINUE_LOOP', nop_func) custom_ops_seen.add(opname) @@ -751,6 +754,12 @@ class Python3Parser(PythonParser): delete_subscr ::= expr expr DELETE_SUBSCR """, nop_func) custom_ops_seen.add(opname) + elif opname == 'GET_ITER': + self.addRule(""" + expr ::= get_iter + attribute ::= expr GET_ITER + """, nop_func) + custom_ops_seen.add(opname) elif opname == 'JUMP_IF_NOT_DEBUG': v = token.attr self.addRule(""" @@ -782,6 +791,12 @@ class Python3Parser(PythonParser): "GET_ITER CALL_FUNCTION_1") self.add_make_function_rule(rule_pat, opname, token.attr, customize) # listcomp is a custom Python3 rule + elif opname == 'LOAD_ATTR': + self.addRule(""" + expr ::= attribute + attribute ::= expr LOAD_ATTR + """, nop_func) + custom_ops_seen.add(opname) elif opname == 'LOAD_LISTCOMP': self.add_unique_rule("expr ::= listcomp", opname, token.attr, customize) elif opname == 'LOAD_SETCOMP': @@ -792,8 +807,12 @@ class Python3Parser(PythonParser): "GET_ITER CALL_FUNCTION_1") self.add_make_function_rule(rule_pat, opname, token.attr, customize) elif opname == 'LOOKUP_METHOD': - # A PyPy speciality - DRY with parse2 - self.addRule("attribute ::= expr LOOKUP_METHOD", nop_func) + # A PyPy speciality - DRY with parse3 + self.addRule(""" + expr ::= attribute + attribute ::= expr LOOKUP_METHOD + """, + nop_func) custom_ops_seen.add(opname) elif opname.startswith('MAKE_CLOSURE'): # DRY with MAKE_FUNCTION