From fedd5e0ba5bb40cbd6cddc7721ae3a7cd9a45654 Mon Sep 17 00:00:00 2001 From: rocky Date: Thu, 9 Jan 2020 22:37:02 -0500 Subject: [PATCH] Better "try" vs. "try"/"else" disambiguation ... via reduction check that was originally only in 2.7 --- uncompyle6/parsers/parse2.py | 22 +++++-------------- uncompyle6/parsers/parse3.py | 22 ++++++++++++------- uncompyle6/parsers/parse35.py | 4 +++- uncompyle6/parsers/reducecheck/__init__.py | 2 +- ...cept_handler.py => except_handler_else.py} | 2 +- uncompyle6/semantics/customize3.py | 2 +- 6 files changed, 26 insertions(+), 28 deletions(-) rename uncompyle6/parsers/reducecheck/{except_handler.py => except_handler_else.py} (93%) diff --git a/uncompyle6/parsers/parse2.py b/uncompyle6/parsers/parse2.py index 18bfc46a..e3390602 100644 --- a/uncompyle6/parsers/parse2.py +++ b/uncompyle6/parsers/parse2.py @@ -27,7 +27,7 @@ that a later phase can turn into a sequence of ASCII text. from __future__ import print_function -from uncompyle6.parsers.reducecheck import (except_handler, tryelsestmt) +from uncompyle6.parsers.reducecheck import (except_handler_else, tryelsestmt) from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func from uncompyle6.parsers.treenode import SyntaxTree from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG @@ -147,10 +147,10 @@ class Python2Parser(PythonParser): # Move to 2.7? 2.6 may use come_froms tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suitec COME_FROM + except_handler_else else_suitec COME_FROM tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suitel COME_FROM + except_handler_else else_suitel COME_FROM try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler COME_FROM @@ -162,16 +162,7 @@ class Python2Parser(PythonParser): except_handler ::= jmp_abs COME_FROM except_stmts END_FINALLY - # except_handler_else is intended to be used only in a - # try_else. The disambiguation comes from reduction rule - # checking where we make sure that the JUMP_FORWARD mismatches - # the JUMP_FORWARD before the END_FINALLY - except_handler_else ::= JUMP_FORWARD COME_FROM except_stmts - END_FINALLY come_froms - - except_handler_else ::= jmp_abs COME_FROM except_stmts - END_FINALLY - + except_handler_else ::= except_handler except_stmts ::= except_stmt+ @@ -650,7 +641,6 @@ class Python2Parser(PythonParser): pass self.check_reduce["and"] = "AST" - self.check_reduce["except_handler"] = "tokens" self.check_reduce["except_handler_else"] = "tokens" self.check_reduce["raise_stmt1"] = "tokens" self.check_reduce["assert_expr_and"] = "AST" @@ -708,8 +698,8 @@ class Python2Parser(PythonParser): jmp_false = ast[1] jump_target = jmp_false[0].attr return jump_target > tokens[last].off2int() - elif lhs in ("except_handler, except_handler_else"): - return except_handler(self, lhs, n, rule, ast, tokens, first, last) + elif lhs == "except_handler_else": + return except_handler_else(self, lhs, n, rule, ast, tokens, first, last) elif lhs in ("raise_stmt1",): # We will assume 'LOAD_ASSERT' will be handled by an assert grammar rule return tokens[first] == "LOAD_ASSERT" and (last >= len(tokens)) diff --git a/uncompyle6/parsers/parse3.py b/uncompyle6/parsers/parse3.py index b9980c02..900f84bc 100644 --- a/uncompyle6/parsers/parse3.py +++ b/uncompyle6/parsers/parse3.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2019 Rocky Bernstein +# Copyright (c) 2015-2020 Rocky Bernstein # Copyright (c) 2005 by Dan Pascu # Copyright (c) 2000-2002 by hartmut Goebel # Copyright (c) 1999 John Aycock @@ -29,6 +29,7 @@ that a later phase can turn into a sequence of ASCII text. import re from uncompyle6.scanners.tok import Token from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func +from uncompyle6.parsers.reducecheck import except_handler_else from uncompyle6.parsers.treenode import SyntaxTree from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from xdis import PYTHON3 @@ -192,6 +193,8 @@ class Python3Parser(PythonParser): POP_BLOCK LOAD_CONST COME_FROM_FINALLY suite_stmts_opt END_FINALLY + except_handler_else ::= except_handler + except_handler ::= jmp_abs COME_FROM except_stmts END_FINALLY except_handler ::= jmp_abs COME_FROM_EXCEPT except_stmts @@ -1419,20 +1422,19 @@ class Python3Parser(PythonParser): """ try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler opt_come_from_except - - tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suite come_from_except_clauses - - tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler else_suite come_froms + try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + except_handler opt_come_from_except tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler else_suitel come_from_except_clauses stmt ::= tryelsestmtl3 + tryelsestmtl3 ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK - except_handler COME_FROM else_suitel + except_handler_else COME_FROM else_suitel opt_come_from_except + tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK + except_handler_else else_suite come_froms """, nop_func ) @@ -1461,6 +1463,7 @@ class Python3Parser(PythonParser): self.check_reduce["ifelsestmt"] = "AST" self.check_reduce["ifstmt"] = "AST" self.check_reduce["annotate_tuple"] = "noAST" + self.check_reduce["except_handler_else"] = "tokens" if not PYTHON3: self.check_reduce["kwarg"] = "noAST" if self.version < 3.6: @@ -1473,10 +1476,13 @@ class Python3Parser(PythonParser): def reduce_is_invalid(self, rule, ast, tokens, first, last): lhs = rule[0] + n = len(tokens) if lhs in ("aug_assign1", "aug_assign2") and ast[0][0] == "and": return True elif lhs == "annotate_tuple": return not isinstance(tokens[first].attr, tuple) + elif lhs in ("except_handler_else"): + return except_handler_else(self, lhs, n, rule, ast, tokens, first, last) elif lhs == "kwarg": arg = tokens[first].attr return not (isinstance(arg, str) or isinstance(arg, unicode)) diff --git a/uncompyle6/parsers/parse35.py b/uncompyle6/parsers/parse35.py index 1a02ce13..1c7870c9 100644 --- a/uncompyle6/parsers/parse35.py +++ b/uncompyle6/parsers/parse35.py @@ -252,7 +252,9 @@ class Python35Parser(Python34Parser): # zero or not in creating a template rule. self.add_unique_rule(rule, token.kind, args_pos, customize) else: - super(Python35Parser, self).custom_classfunc_rule(opname, token, customize, *args) + super(Python35Parser, self).custom_classfunc_rule(opname, token, customize, *args + ) + class Python35ParserSingle(Python35Parser, PythonParserSingle): pass diff --git a/uncompyle6/parsers/reducecheck/__init__.py b/uncompyle6/parsers/reducecheck/__init__.py index b969fcc9..e5f50202 100644 --- a/uncompyle6/parsers/reducecheck/__init__.py +++ b/uncompyle6/parsers/reducecheck/__init__.py @@ -1,5 +1,5 @@ from uncompyle6.parsers.reducecheck.and_check import * -from uncompyle6.parsers.reducecheck.except_handler import * +from uncompyle6.parsers.reducecheck.except_handler_else import * from uncompyle6.parsers.reducecheck.ifelsestmt import * from uncompyle6.parsers.reducecheck.iflaststmt import * from uncompyle6.parsers.reducecheck.ifstmt import * diff --git a/uncompyle6/parsers/reducecheck/except_handler.py b/uncompyle6/parsers/reducecheck/except_handler_else.py similarity index 93% rename from uncompyle6/parsers/reducecheck/except_handler.py rename to uncompyle6/parsers/reducecheck/except_handler_else.py index 8870c31b..a5b012c2 100644 --- a/uncompyle6/parsers/reducecheck/except_handler.py +++ b/uncompyle6/parsers/reducecheck/except_handler_else.py @@ -1,6 +1,6 @@ # Copyright (c) 2020 Rocky Bernstein -def except_handler(self, lhs, n, rule, ast, tokens, first, last): +def except_handler_else(self, lhs, n, rule, ast, tokens, first, last): # FIXME: expand this to other versions if self.version not in (2.7, 3.5): return False diff --git a/uncompyle6/semantics/customize3.py b/uncompyle6/semantics/customize3.py index 36293392..39ee3e9d 100644 --- a/uncompyle6/semantics/customize3.py +++ b/uncompyle6/semantics/customize3.py @@ -443,7 +443,7 @@ def customize_for_version3(self, version): "tryelsestmtl3": ( "%|try:\n%+%c%-%c%|else:\n%+%c%-", (1, "suite_stmts_opt"), - (3, "except_handler"), + (3, "except_handler_else"), (5, "else_suitel"), ), "LOAD_CLASSDEREF": ("%{pattr}",),