Better "try" vs. "try"/"else" disambiguation ...

via reduction check that was originally only in 2.7
This commit is contained in:
rocky
2020-01-09 22:37:02 -05:00
parent 7bcebf8656
commit fedd5e0ba5
6 changed files with 26 additions and 28 deletions

View File

@@ -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))

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2019 Rocky Bernstein
# Copyright (c) 2015-2020 Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# 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))

View File

@@ -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

View File

@@ -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 *

View File

@@ -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

View File

@@ -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}",),