More accurate ranges of try blocks in 3.x

This commit is contained in:
rocky
2017-03-05 00:05:52 -05:00
parent ea1651d8ca
commit 4f2ae2f603
4 changed files with 36 additions and 6 deletions

View File

@@ -40,7 +40,9 @@ def test_grammar():
ignore_set = set(
"""
JUMP_BACK CONTINUE RETURN_END_IF
COME_FROM COME_FROM_EXCEPT COME_FROM_LOOP COME_FROM_WITH
COME_FROM COME_FROM_EXCEPT
COME_FROM_EXCEPT_CLAUSE
COME_FROM_LOOP COME_FROM_WITH
COME_FROM_FINALLY ELSE
LOAD_GENEXPR LOAD_ASSERT LOAD_SETCOMP LOAD_DICTCOMP
LAMBDA_MARKER RETURN_LAST

View File

@@ -180,14 +180,17 @@ class Python3Parser(PythonParser):
POP_BLOCK LOAD_CONST
come_from_or_finally suite_stmts_opt END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite come_from_except_clauses
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite come_froms
tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitec COME_FROM
try_middle else_suitec come_from_except_clauses
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitel COME_FROM
try_middle else_suitel come_from_except_clauses
try_middle ::= jmp_abs COME_FROM except_stmts
END_FINALLY
@@ -254,7 +257,10 @@ class Python3Parser(PythonParser):
def p_misc3(self, args):
"""
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts END_FINALLY COME_FROM
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY COME_FROM
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY COME_FROM_EXCEPT_CLAUSE
for_block ::= l_stmts_opt opt_come_from_loop JUMP_BACK
for_block ::= l_stmts
@@ -285,10 +291,13 @@ class Python3Parser(PythonParser):
"""
opt_come_from_except ::= COME_FROM_EXCEPT
opt_come_from_except ::= come_froms
opt_come_from_except ::= come_from_except_clauses
come_froms ::= come_froms COME_FROM
come_froms ::=
come_froms ::= COME_FROM*
come_from_except_clauses ::= COME_FROM_EXCEPT_CLAUSE+
opt_come_from_loop ::= opt_come_from_loop COME_FROM_LOOP
opt_come_from_loop ::= opt_come_from_loop COME_FROM_LOOP
opt_come_from_loop ::=

View File

@@ -21,6 +21,19 @@ class Python33Parser(Python32Parser):
iflaststmt ::= testexpr c_stmts_opt33
c_stmts_opt33 ::= JUMP_BACK JUMP_ABSOLUTE c_stmts_opt
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_from
# Python 3.5+ has jump optimization to remove the redundant
# jump_excepts. But in 3.3 we need them added
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite
jump_excepts come_from_except_clauses
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle
jump_excepts come_from_except_clauses
jump_excepts ::= jump_except+
"""
class Python33ParserSingle(Python33Parser, PythonParserSingle):

View File

@@ -221,6 +221,9 @@ class Scanner3(Scanner):
come_from_type = opname[len('SETUP_'):]
come_from_name = 'COME_FROM_%s' % come_from_type
pass
elif inst.offset in self.except_targets:
come_from_name = 'COME_FROM_EXCEPT_CLAUSE'
pass
tokens.append(Token(come_from_name,
None, repr(jump_offset),
offset='%s_%s' % (inst.offset, jump_idx),
@@ -443,6 +446,7 @@ class Scanner3(Scanner):
# Map fixed jumps to their real destination
self.fixed_jumps = {}
self.except_targets = {}
self.ignore_if = set()
self.build_statement_indices()
self.else_start = {}
@@ -907,6 +911,8 @@ class Scanner3(Scanner):
target = self.get_target(next_offset)
if target > next_offset:
self.fixed_jumps[next_offset] = target
self.except_targets[target] = next_offset
elif op == self.opc.SETUP_FINALLY:
target = self.get_target(offset)
end = self.restrict_to_parent(target, parent)