You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Move some parse2 reduction rules into reducecheck
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015-2019 Rocky Bernstein
|
# Copyright (c) 2015-2020 Rocky Bernstein
|
||||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
#
|
#
|
||||||
# Copyright (c) 1999 John Aycock
|
# Copyright (c) 1999 John Aycock
|
||||||
@@ -27,6 +27,7 @@ that a later phase can turn into a sequence of ASCII text.
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from uncompyle6.parsers.reducecheck import (except_handler, tryelsestmt)
|
||||||
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
|
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
@@ -668,6 +669,7 @@ class Python2Parser(PythonParser):
|
|||||||
if tokens is None:
|
if tokens is None:
|
||||||
return False
|
return False
|
||||||
lhs = rule[0]
|
lhs = rule[0]
|
||||||
|
n = len(tokens)
|
||||||
|
|
||||||
if rule == ("and", ("expr", "jmp_false", "expr", "\\e_come_from_opt")):
|
if rule == ("and", ("expr", "jmp_false", "expr", "\\e_come_from_opt")):
|
||||||
# If the instruction after the instructions forming the "and" is an "YIELD_VALUE"
|
# If the instruction after the instructions forming the "and" is an "YIELD_VALUE"
|
||||||
@@ -707,30 +709,7 @@ class Python2Parser(PythonParser):
|
|||||||
jump_target = jmp_false[0].attr
|
jump_target = jmp_false[0].attr
|
||||||
return jump_target > tokens[last].off2int()
|
return jump_target > tokens[last].off2int()
|
||||||
elif lhs in ("except_handler, except_handler_else"):
|
elif lhs in ("except_handler, except_handler_else"):
|
||||||
|
return except_handler(self, lhs, n, rule, ast, tokens, first, last)
|
||||||
# FIXME: expand this to other 2.x version
|
|
||||||
if self.version != 2.7: return False
|
|
||||||
|
|
||||||
if tokens[first] in ("JUMP_FORWARD", "JUMP_ABSOLUTE"):
|
|
||||||
first_jump_target = tokens[first].pattr
|
|
||||||
last = min(last, len(tokens)-1)
|
|
||||||
for i in range(last, first, -1):
|
|
||||||
if tokens[i] == "END_FINALLY":
|
|
||||||
i -= 1
|
|
||||||
second_jump = tokens[i]
|
|
||||||
if second_jump in ("JUMP_FORWARD", "JUMP_ABSOLUTE"):
|
|
||||||
second_jump_target = second_jump.pattr
|
|
||||||
equal_target = second_jump_target == first_jump_target
|
|
||||||
if equal_target:
|
|
||||||
return lhs != "except_handler"
|
|
||||||
else:
|
|
||||||
return lhs != "except_handler_else"
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
elif lhs in ("raise_stmt1",):
|
elif lhs in ("raise_stmt1",):
|
||||||
# We will assume 'LOAD_ASSERT' will be handled by an assert grammar rule
|
# We will assume 'LOAD_ASSERT' will be handled by an assert grammar rule
|
||||||
return tokens[first] == "LOAD_ASSERT" and (last >= len(tokens))
|
return tokens[first] == "LOAD_ASSERT" and (last >= len(tokens))
|
||||||
@@ -741,35 +720,7 @@ class Python2Parser(PythonParser):
|
|||||||
op = ast[0][0]
|
op = ast[0][0]
|
||||||
return op.kind in ("and", "or")
|
return op.kind in ("and", "or")
|
||||||
elif lhs in ("tryelsestmt", "tryelsestmtl"):
|
elif lhs in ("tryelsestmt", "tryelsestmtl"):
|
||||||
# Check the end of the except handler that there isn't a jump from
|
return tryelsestmt(self, lhs, n, rule, ast, tokens, first, last)
|
||||||
# inside the except handler to the end. If that happens
|
|
||||||
# then this is a "try" with no "else".
|
|
||||||
except_handler = ast[3]
|
|
||||||
if except_handler == "except_handler":
|
|
||||||
|
|
||||||
come_from = except_handler[-1]
|
|
||||||
# We only care about the *first* come_from because that is the
|
|
||||||
# the innermost one. So if the "tryelse" is invalid (should be a "try")
|
|
||||||
# ti will be invalid here.
|
|
||||||
if come_from == "COME_FROM":
|
|
||||||
first_come_from = except_handler[-1]
|
|
||||||
elif come_from == "END_FINALLY":
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
assert come_from == "come_froms"
|
|
||||||
first_come_from = come_from[0]
|
|
||||||
|
|
||||||
leading_jump = except_handler[0]
|
|
||||||
|
|
||||||
# We really don't care that this is a jump per-se. But
|
|
||||||
# we could also check that this jumps to the end of the except if
|
|
||||||
# desired.
|
|
||||||
if isinstance(leading_jump, SyntaxTree):
|
|
||||||
except_handler_first_offset = leading_jump.first_child().off2int()
|
|
||||||
else:
|
|
||||||
except_handler_first_offset = leading_jump.off2int()
|
|
||||||
return first_come_from.attr > except_handler_first_offset
|
|
||||||
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
from uncompyle6.parsers.reducecheck.and_check import *
|
from uncompyle6.parsers.reducecheck.and_check import *
|
||||||
|
from uncompyle6.parsers.reducecheck.except_handler import *
|
||||||
from uncompyle6.parsers.reducecheck.ifelsestmt import *
|
from uncompyle6.parsers.reducecheck.ifelsestmt import *
|
||||||
from uncompyle6.parsers.reducecheck.iflaststmt import *
|
from uncompyle6.parsers.reducecheck.iflaststmt import *
|
||||||
from uncompyle6.parsers.reducecheck.ifstmt import *
|
from uncompyle6.parsers.reducecheck.ifstmt import *
|
||||||
from uncompyle6.parsers.reducecheck.ifstmts_jump import *
|
from uncompyle6.parsers.reducecheck.ifstmts_jump import *
|
||||||
from uncompyle6.parsers.reducecheck.or_check import *
|
from uncompyle6.parsers.reducecheck.or_check import *
|
||||||
|
from uncompyle6.parsers.reducecheck.tryelsestmt import *
|
||||||
from uncompyle6.parsers.reducecheck.while1elsestmt import *
|
from uncompyle6.parsers.reducecheck.while1elsestmt import *
|
||||||
from uncompyle6.parsers.reducecheck.while1stmt import *
|
from uncompyle6.parsers.reducecheck.while1stmt import *
|
||||||
|
27
uncompyle6/parsers/reducecheck/except_handler.py
Normal file
27
uncompyle6/parsers/reducecheck/except_handler.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2020 Rocky Bernstein
|
||||||
|
|
||||||
|
def except_handler(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
|
||||||
|
|
||||||
|
if tokens[first] in ("JUMP_FORWARD", "JUMP_ABSOLUTE"):
|
||||||
|
first_jump_target = tokens[first].pattr
|
||||||
|
last = min(last, len(tokens)-1)
|
||||||
|
for i in range(last, first, -1):
|
||||||
|
if tokens[i] == "END_FINALLY":
|
||||||
|
i -= 1
|
||||||
|
second_jump = tokens[i]
|
||||||
|
if second_jump in ("JUMP_FORWARD", "JUMP_ABSOLUTE"):
|
||||||
|
second_jump_target = second_jump.pattr
|
||||||
|
equal_target = second_jump_target == first_jump_target
|
||||||
|
if equal_target:
|
||||||
|
return lhs != "except_handler"
|
||||||
|
else:
|
||||||
|
return lhs != "except_handler_else"
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
return False
|
34
uncompyle6/parsers/reducecheck/tryelsestmt.py
Normal file
34
uncompyle6/parsers/reducecheck/tryelsestmt.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Copyright (c) 2020 Rocky Bernstein
|
||||||
|
|
||||||
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
|
|
||||||
|
def tryelsestmt(self, lhs, n, rule, ast, tokens, first, last):
|
||||||
|
# Check the end of the except handler that there isn't a jump from
|
||||||
|
# inside the except handler to the end. If that happens
|
||||||
|
# then this is a "try" with no "else".
|
||||||
|
except_handler = ast[3]
|
||||||
|
if except_handler == "except_handler":
|
||||||
|
|
||||||
|
come_from = except_handler[-1]
|
||||||
|
# We only care about the *first* come_from because that is the
|
||||||
|
# the innermost one. So if the "tryelse" is invalid (should be a "try")
|
||||||
|
# ti will be invalid here.
|
||||||
|
if come_from == "COME_FROM":
|
||||||
|
first_come_from = except_handler[-1]
|
||||||
|
elif come_from == "END_FINALLY":
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
assert come_from == "come_froms"
|
||||||
|
first_come_from = come_from[0]
|
||||||
|
|
||||||
|
leading_jump = except_handler[0]
|
||||||
|
|
||||||
|
# We really don't care that this is a jump per-se. But
|
||||||
|
# we could also check that this jumps to the end of the except if
|
||||||
|
# desired.
|
||||||
|
if isinstance(leading_jump, SyntaxTree):
|
||||||
|
except_handler_first_offset = leading_jump.first_child().off2int()
|
||||||
|
else:
|
||||||
|
except_handler_first_offset = leading_jump.off2int()
|
||||||
|
return first_come_from.attr > except_handler_first_offset
|
||||||
|
return False
|
Reference in New Issue
Block a user