Forelse reduction checks on 2.6

This commit is contained in:
rocky
2020-07-06 09:18:13 -04:00
parent 084e183577
commit ef59b9c304
6 changed files with 46 additions and 12 deletions

View File

@@ -45,7 +45,6 @@ SKIP_TESTS=(
[test_grammar.py]=1 # Too many stmts. Handle large stmts [test_grammar.py]=1 # Too many stmts. Handle large stmts
[test_grp.py]=1 # Long test - might work Control flow? [test_grp.py]=1 # Long test - might work Control flow?
[test_pep247.py]=1 # Long test - might work? Control flow? [test_pep247.py]=1 # Long test - might work? Control flow?
[test_pwd.py]=1 # Long test - might work? Control flow?
[test_socketserver.py]=1 # -- test takes too long to run: 40 seconds [test_socketserver.py]=1 # -- test takes too long to run: 40 seconds
[test_threading.py]=1 # test takes too long to run: 11 seconds [test_threading.py]=1 # test takes too long to run: 11 seconds
[test_thread.py]=1 # test takes too long to run: 36 seconds [test_thread.py]=1 # test takes too long to run: 36 seconds

View File

@@ -56,7 +56,6 @@ SKIP_TESTS=(
[test_pdb.py]=1 # Line-number specific [test_pdb.py]=1 # Line-number specific
[test_pep277.py]=1 # it fails on its own [test_pep277.py]=1 # it fails on its own
[test_plistlib.py]=1 # it fails on its own [test_plistlib.py]=1 # it fails on its own
[test_pwd.py]=1 # Long test - might work? Control flow?
[test_pyclbr.py]=1 # Investigate [test_pyclbr.py]=1 # Investigate
[test_rgbimg.py]=1 # it fails on its own [test_rgbimg.py]=1 # it fails on its own
[test_scriptpackages.py]=1 # it fails on its own [test_scriptpackages.py]=1 # it fails on its own

View File

@@ -7,7 +7,6 @@ SKIP_TESTS=(
# assert 0 # shouldn't reach here. # assert 0 # shouldn't reach here.
[test_shutil.py]=1 [test_shutil.py]=1
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test___all__.py]=1 # it fails on its own [test___all__.py]=1 # it fails on its own
[test_aepack.py]=1 # Fails on its own [test_aepack.py]=1 # Fails on its own
@@ -61,7 +60,6 @@ SKIP_TESTS=(
[test_pep277.py]=1 # it fails on its own [test_pep277.py]=1 # it fails on its own
[test_pyclbr.py]=1 # Investigate [test_pyclbr.py]=1 # Investigate
[test_pwd.py]=1 # Long test - might work? Control flow?
[test_py3kwarn.py]=1 # it fails on its own [test_py3kwarn.py]=1 # it fails on its own
[test_scriptpackages.py]=1 # it fails on its own [test_scriptpackages.py]=1 # it fails on its own

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2017-2019 Rocky Bernstein # Copyright (c) 2017-2020 Rocky Bernstein
""" """
spark grammar differences over Python2 for Python 2.6. spark grammar differences over Python2 for Python 2.6.
""" """
@@ -6,9 +6,7 @@ spark grammar differences over Python2 for Python 2.6.
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from uncompyle6.parsers.parse2 import Python2Parser from uncompyle6.parsers.parse2 import Python2Parser
from uncompyle6.parsers.reducecheck import ( from uncompyle6.parsers.reducecheck import (except_handler, tryelsestmt)
except_handler,
)
class Python26Parser(Python2Parser): class Python26Parser(Python2Parser):
@@ -27,7 +25,11 @@ class Python26Parser(Python2Parser):
except_handler ::= JUMP_FORWARD COME_FROM except_stmts except_handler ::= JUMP_FORWARD COME_FROM except_stmts
come_froms_pop END_FINALLY come_froms come_froms_pop END_FINALLY come_froms
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY except_handler ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
POP_TOP END_FINALLY
come_froms come_froms
except_handler ::= jmp_abs COME_FROM except_stmts except_handler ::= jmp_abs COME_FROM except_stmts
@@ -36,6 +38,7 @@ class Python26Parser(Python2Parser):
except_handler ::= jmp_abs COME_FROM except_stmts except_handler ::= jmp_abs COME_FROM except_stmts
END_FINALLY JUMP_FORWARD END_FINALLY JUMP_FORWARD
# Sometimes we don't put in COME_FROM to the next statement # Sometimes we don't put in COME_FROM to the next statement
# like we do in 2.7. Perhaps we should? # like we do in 2.7. Perhaps we should?
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
@@ -350,21 +353,28 @@ class Python26Parser(Python2Parser):
super(Python26Parser, self).customize_grammar_rules(tokens, customize) super(Python26Parser, self).customize_grammar_rules(tokens, customize)
self.reduce_check_table = { self.reduce_check_table = {
"except_handler": except_handler, "except_handler": except_handler,
"tryelsestmt": tryelsestmt,
"tryelsestmtl": tryelsestmt,
} }
self.check_reduce['and'] = 'AST' self.check_reduce['and'] = 'AST'
self.check_reduce['assert_expr_and'] = 'AST' self.check_reduce['assert_expr_and'] = 'AST'
self.check_reduce["except_handler"] = "tokens"
self.check_reduce["ifstmt"] = "tokens" self.check_reduce["ifstmt"] = "tokens"
self.check_reduce["ifelsestmt"] = "AST" self.check_reduce["ifelsestmt"] = "AST"
self.check_reduce["forelselaststmtl"] = "tokens"
self.check_reduce["forelsestmt"] = "tokens"
self.check_reduce['list_for'] = 'AST' self.check_reduce['list_for'] = 'AST'
self.check_reduce['try_except'] = 'tokens' self.check_reduce['try_except'] = 'tokens'
self.check_reduce['tryelsestmt'] = 'AST' self.check_reduce['tryelsestmt'] = 'AST'
self.check_reduce['tryelsestmtl'] = 'AST'
def reduce_is_invalid(self, rule, ast, tokens, first, last): def reduce_is_invalid(self, rule, ast, tokens, first, last):
invalid = super(Python26Parser, invalid = super(Python26Parser,
self).reduce_is_invalid(rule, ast, self).reduce_is_invalid(rule, ast,
tokens, first, last) tokens, first, last)
lhs = rule[0]
if invalid or tokens is None: if invalid or tokens is None:
return invalid return invalid
if rule in ( if rule in (
@@ -397,6 +407,16 @@ class Python26Parser(Python2Parser):
return not (jmp_target == tokens[test_index].offset or return not (jmp_target == tokens[test_index].offset or
tokens[last].pattr == jmp_false.pattr) tokens[last].pattr == jmp_false.pattr)
elif lhs in ("forelselaststmtl", "forelsestmt"):
# print("XXX", first, last)
# for t in range(first, last):
# print(tokens[t])
# print("=" * 30)
# FIXME: Figure out why this doesn't work on
# bytecode-1.4/anydbm.pyc
if self.version == 1.4:
return False
return tokens[last-1].off2int() > tokens[first].attr
elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")): elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")):
for i in range(last-1, last-4, -1): for i in range(last-1, last-4, -1):
t = tokens[i] t = tokens[i]
@@ -413,7 +433,11 @@ class Python26Parser(Python2Parser):
# The JUMP_ABSOLUTE has to be to the last POP_TOP or this is invalid # The JUMP_ABSOLUTE has to be to the last POP_TOP or this is invalid
ja_attr = ast[4].attr ja_attr = ast[4].attr
return tokens[last].offset != ja_attr return tokens[last].offset != ja_attr
elif rule[0] == 'try_except': elif lhs == 'try_except':
# FIXME: Figure out why this doesn't work on
# bytecode-1.4/anydbm.pyc
if self.version == 1.4:
return False
# We need to distingush try_except from tryelsestmt and we do that # We need to distingush try_except from tryelsestmt and we do that
# by checking the jump before the END_FINALLY # by checking the jump before the END_FINALLY
# If we have: # If we have:
@@ -430,12 +454,12 @@ class Python26Parser(Python2Parser):
last -= 1 last -= 1
if (tokens[last] == 'COME_FROM' if (tokens[last] == 'COME_FROM'
and tokens[last-1] == 'END_FINALLY' and tokens[last-1] == 'END_FINALLY'
and tokens[last-2] == 'POP_TOP'): and tokens[last-2] == 'POP_TOP'):
# A jump of 2 is a jump around POP_TOP, END_FINALLY which # A jump of 2 is a jump around POP_TOP, END_FINALLY which
# would indicate try/else rather than try # would indicate try/else rather than try
return (tokens[last-3].kind not in frozenset(('JUMP_FORWARD', 'RETURN_VALUE')) return (tokens[last-3].kind not in frozenset(('JUMP_FORWARD', 'RETURN_VALUE'))
or (tokens[last-3] == 'JUMP_FORWARD' and tokens[last-3].attr != 2)) or (tokens[last-3] == 'JUMP_FORWARD' and tokens[last-3].attr != 2))
elif rule[0] == 'tryelsestmt': elif lhs == 'tryelsestmt':
# We need to distingush try_except from tryelsestmt and we do that # We need to distingush try_except from tryelsestmt and we do that
# by making sure that the jump before the except handler jumps to # by making sure that the jump before the except handler jumps to

View File

@@ -6,6 +6,11 @@ def except_handler(self, lhs, n, rule, ast, tokens, first, last):
# print(tokens[t]) # print(tokens[t])
# print("=" * 30) # print("=" * 30)
# FIXME: Figure out why this doesn't work on
# bytecode-1.4/anydbm.pyc
if self.version != 1.4:
return False
# Make sure come froms all come from within "except_handler". # Make sure come froms all come from within "except_handler".
if end_token != "COME_FROM": if end_token != "COME_FROM":
return False return False

View File

@@ -6,7 +6,13 @@ def tryelsestmt(self, lhs, n, rule, ast, tokens, first, last):
# Check the end of the except handler that there isn't a jump from # Check the end of the except handler that there isn't a jump from
# inside the except handler to the end. If that happens # inside the except handler to the end. If that happens
# then this is a "try" with no "else". # then this is a "try" with no "else".
# for t in range(first, last):
# print(tokens[t])
# print("=" * 30)
except_handler = ast[3] except_handler = ast[3]
if except_handler == "except_handler_else": if except_handler == "except_handler_else":
except_handler = except_handler[0] except_handler = except_handler[0]
if except_handler == "except_handler": if except_handler == "except_handler":
@@ -32,5 +38,8 @@ def tryelsestmt(self, lhs, n, rule, ast, tokens, first, last):
except_handler_first_offset = leading_jump.first_child().off2int() except_handler_first_offset = leading_jump.first_child().off2int()
else: else:
except_handler_first_offset = leading_jump.off2int() except_handler_first_offset = leading_jump.off2int()
if first_come_from.attr < tokens[first].offset:
return True
return first_come_from.attr > except_handler_first_offset return first_come_from.attr > except_handler_first_offset
return False return False