diff --git a/uncompyle6/parser.py b/uncompyle6/parser.py index 46be2dcb..b880dc9e 100644 --- a/uncompyle6/parser.py +++ b/uncompyle6/parser.py @@ -485,6 +485,7 @@ class PythonParser(GenericASTBuilder): ret_expr_or_cond ::= ret_cond ret_expr_or_cond ::= ret_cond_not + # Note: Python < 2.7 doesn't use this. Remove from here? ret_and ::= expr JUMP_IF_FALSE_OR_POP ret_expr_or_cond COME_FROM ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF ret_expr_or_cond diff --git a/uncompyle6/parsers/parse26.py b/uncompyle6/parsers/parse26.py index 46b620d8..dc28617a 100644 --- a/uncompyle6/parsers/parse26.py +++ b/uncompyle6/parsers/parse26.py @@ -20,19 +20,36 @@ class Python26Parser(Python2Parser): JUMP_IF_FALSE POP_TOP POP_TOP POP_TOP POP_TOP except_cond2 ::= DUP_TOP expr COMPARE_OP JUMP_IF_FALSE POP_TOP POP_TOP designator POP_TOP + + # Might be a bug from when COME_FROM wasn't properly handled try_middle ::= JUMP_FORWARD COME_FROM except_stmts POP_TOP END_FINALLY come_froms - try_middle ::= JUMP_FORWARD COME_FROM except_stmts - COME_FROM POP_TOP END_FINALLY come_froms + try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY come_froms + try_middle ::= JUMP_FORWARD COME_FROM except_stmts + come_from_pop END_FINALLY come_froms + try_middle ::= JUMP_FORWARD COME_FROM except_stmts + END_FINALLY come_froms + try_middle ::= jmp_abs COME_FROM except_stmts POP_TOP END_FINALLY + try_middle ::= jmp_abs COME_FROM except_stmts + come_from_pop END_FINALLY + + try_middle ::= jmp_abs COME_FROM except_stmts + END_FINALLY + + trystmt ::= SETUP_EXCEPT suite_stmts_opt come_from_pop + try_middle + + # Sometimes we don't put in COME_FROM to the next statement + # like we do in 2.7. Perhaps we should? trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle - except_suite ::= c_stmts_opt JUMP_FORWARD POP_TOP + except_suite ::= c_stmts_opt JUMP_FORWARD come_from_pop # Python 3 also has this. come_froms ::= come_froms COME_FROM @@ -53,15 +70,20 @@ class Python26Parser(Python2Parser): """ jmp_true ::= JUMP_IF_TRUE POP_TOP jmp_false ::= JUMP_IF_FALSE POP_TOP - jf_pop ::= JUMP_FORWARD COME_FROM POP_TOP - jb_pop ::= JUMP_BACK COME_FROM POP_TOP + jf_pop ::= JUMP_FORWARD come_from_pop + jb_pop ::= JUMP_BACK come_from_pop + + # This is what happens after a jump where + # we start a new block. For reasons I don't fully + # understand, there is also a value on the top of the stack + come_from_pop ::= COME_FROM POP_TOP _ifstmts_jump ::= c_stmts_opt jf_pop COME_FROM """ def p_stmt26(self, args): """ - assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 POP_TOP + assert ::= assert_expr jmp_true LOAD_ASSERT RAISE_VARARGS_1 come_from_pop ifelsestmt ::= testexpr c_stmts_opt jf_pop else_suite COME_FROM """ @@ -80,8 +102,16 @@ class Python26Parser(Python2Parser): def p_ret26(self, args): ''' - ret_cond ::= expr jmp_false expr RETURN_END_IF COME_FROM POP_TOP ret_expr_or_cond - ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM + 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 come_from_pop ret_expr_or_cond + ret_cond ::= expr jmp_false expr ret_expr_or_cond + ret_cond_not ::= expr jmp_true expr RETURN_END_IF come_from_pop ret_expr_or_cond + ''' + + def p_except26(self, args): + ''' + except_suite ::= c_stmts_opt jmp_abs new_block '''