Merge branch 'master' of github.com:rocky/python-uncompyle6

This commit is contained in:
rocky 2017-12-03 09:35:20 -05:00
commit 0724dc1c0e
19 changed files with 144 additions and 138 deletions

View File

@ -1,6 +1,9 @@
# From 2.6.9 ConfigParser.py
# Note this can only be compiled in Python 2.x
#
# Note: this can only be compiled in Python 2.x
# Note also name "except_as" is a little bit of
# a misnomer since this is 2.7+ lingo for
# 2.6- syntax which we use here.
# Bug was being able to handle:
# except KeyError, e
# vs 2.6+.
@ -17,9 +20,12 @@
try:
value = "foo"
except RuntimeError:
# Test ensuring parens around (a, b, c) in
# except_cond2 or except_cond3
except RuntimeError, (a, b, c):
# Test:
# raise_stmt3 ::= expr expr expr RAISE_VARARGS_3
raise 1, 2, 3
raise a, b, c
except KeyError, e:
raise RuntimeError('foo')

View File

@ -1,7 +1,7 @@
# From PyPy 2.7 argparse.py
# PyPY reduces branches as a result of the return statement
# So we need a new rules for try_except and try_middle which we
# suffix with _pypy, e.g. try_except_pypy, and try_middle_pypy
# So we need a new rules for try_except and except_handler which we
# suffix with _pypy, e.g. try_except_pypy, and except_handler_pypy
def call(self, string):
try:
return open(string, self, self._bufsize)

View File

@ -1,6 +1,6 @@
# Tests:
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
# try_middle COME_FROM
# except_handler COME_FROM
# except_stmt ::= except
try:
@ -10,7 +10,7 @@ except:
# Tests:
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
# try_middle COME_FROM
# except_handler COME_FROM
# except_stmt ::= except_cond1 except_suite
# except_suite ::= ...

View File

@ -1,8 +1,8 @@
# Tests:
# forstmt ::= SETUP_LOOP expr _for store for_block POP_BLOCK COME_FROM
# for_block ::= l_stmts_opt JUMP_BACK
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM
# try_middle ::= jmp_abs COME_FROM except_stmts END_FINALLY
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler COME_FROM
# except_handler ::= jmp_abs COME_FROM except_stmts END_FINALLY
# Had a bug with the end of the except matching the end of the
# for loop.

View File

@ -2,12 +2,12 @@
#
# tryfinallystmt ::= SETUP_FINALLY suite_stmts POP_BLOCK LOAD_CONST COME_FROM suite_stmts_opt END_FINALLY
# suite_stmts_opt ::= suite_stmts
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM
# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler COME_FROM
# except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# except_stmt ::= except_cond1 except_suite
# except_cond1 ::= DUP_TOP expr COMPARE_OP jmp_false POP_TOP POP_TOP POP_TOP
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle COME_FROM
# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler COME_FROM
# except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# except_cond1 ::= DUP_TOP expr COMPARE_OP jmp_false POP_TOP POP_TOP POP_TOP
try:
try:
@ -21,15 +21,15 @@ finally:
x = 4
# Tests Python3:
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle come_froms
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler come_froms
# come_froms ::= COME_FROM COME_FROM
# START ::= |- stmts
# stmts ::= sstmt
# sstmt ::= stmt
# stmt ::= try_except
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle come_froms
# try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler come_froms
# come_froms ::= COME_FROM
# try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
# Python2 doesn't have the come_froms (which allows for 3 successive COME_FROMs)
# it does place 2 COME_FROMs at the end of this code.

View File

@ -3,11 +3,11 @@
# end of if can come from both finishing loop
# and not taking the if.
# whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK \e__come_from
# whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK \e__come_froms
# _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD \e__come_from
# ifstmt ::= testexpr _ifstmts_jump
# _come_from ::= _come_from COME_FROM
# _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_from
# _come_froms ::= _come_froms COME_FROM
# _ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_froms
def splitext(p, sep, altsep, extsep):
if altsep > extsep:

View File

@ -12,10 +12,8 @@ typeset -A SKIP_TESTS
case $PYVERSION in
2.4)
SKIP_TESTS=( [test_binop.py]=1 # need to fix tryelse
[test_bool.py]=1 # need to fix tryelse
[test_call.py]=1 # need to fix tryelse
[test_cgi.py]=1 # need to fix tryelse
[test_class.py]=1 # need to fix tryelse
[test_codecs.py]=1 # need to fix tryelse
[test_dis.py]=1 # We change line numbers - duh!
)
;;

View File

@ -33,7 +33,7 @@ class PythonParser(GenericASTBuilder):
# FIXME: customize per python parser version
nt_list = [
'stmts', 'except_stmts', '_stmts', 'load_attrs',
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_from',
'exprlist', 'kvlist', 'kwargs', 'come_froms', '_come_froms',
'importlist',
# Python < 3
'print_items',
@ -306,9 +306,11 @@ class PythonParser(GenericASTBuilder):
_jump ::= JUMP_FORWARD
_jump ::= JUMP_BACK
# Zero or more COME_FROMs
# loops can have this
_come_from ::= COME_FROM*
# Zero or more COME_FROMs - loops can have this
_come_froms ::= COME_FROM*
# One or more COME_FROMs - joins of tryelse's have this
come_froms ::= COME_FROM+
# Zero or one COME_FROM
# And/or expressions have this
@ -360,19 +362,19 @@ class PythonParser(GenericASTBuilder):
"""
_for ::= GET_ITER FOR_ITER
for_block ::= l_stmts_opt _come_from JUMP_BACK
for_block ::= l_stmts_opt _come_froms JUMP_BACK
forstmt ::= SETUP_LOOP expr _for store
for_block POP_BLOCK _come_from
for_block POP_BLOCK _come_froms
forelsestmt ::= SETUP_LOOP expr _for store
for_block POP_BLOCK else_suite _come_from
for_block POP_BLOCK else_suite _come_froms
forelselaststmt ::= SETUP_LOOP expr _for store
for_block POP_BLOCK else_suitec _come_from
for_block POP_BLOCK else_suitec _come_froms
forelselaststmtl ::= SETUP_LOOP expr _for store
for_block POP_BLOCK else_suitel _come_from
for_block POP_BLOCK else_suitel _come_froms
"""
def p_import20(self, args):
@ -495,7 +497,7 @@ class PythonParser(GenericASTBuilder):
compare_single ::= expr expr COMPARE_OP
# A compare_chained is two comparisions like x <= y <= z
compare_chained ::= expr compare_chained1 ROT_TWO POP_TOP _come_from
compare_chained ::= expr compare_chained1 ROT_TWO POP_TOP _come_froms
compare_chained2 ::= expr COMPARE_OP JUMP_FORWARD
# Non-null kvlist items are broken out in the indiviual grammars

View File

@ -129,24 +129,24 @@ class Python2Parser(PythonParser):
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK
# this is nested inside a try_except
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST
COME_FROM suite_stmts_opt END_FINALLY
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
POP_BLOCK LOAD_CONST
COME_FROM suite_stmts_opt END_FINALLY
# Move to 2.7? 2.6 may use come_froms
tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitec COME_FROM
tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler else_suitec COME_FROM
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitel COME_FROM
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler else_suitel COME_FROM
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle COME_FROM
except_handler COME_FROM
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM
try_middle ::= jmp_abs COME_FROM except_stmts
END_FINALLY
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM
except_handler ::= jmp_abs COME_FROM except_stmts
END_FINALLY
except_stmts ::= except_stmt+
@ -415,8 +415,8 @@ class Python2Parser(PythonParser):
# always be the case.
self.add_unique_rules([
"stmt ::= try_except_pypy",
"try_except_pypy ::= SETUP_EXCEPT suite_stmts_opt try_middle_pypy",
"try_middle_pypy ::= COME_FROM except_stmts END_FINALLY COME_FROM"
"try_except_pypy ::= SETUP_EXCEPT suite_stmts_opt except_handler_pypy",
"except_handler_pypy ::= COME_FROM except_stmts END_FINALLY COME_FROM"
], customize)
continue
elif opname == 'SETUP_FINALLY':

View File

@ -33,7 +33,7 @@ class Python25Parser(Python26Parser):
store ::= STORE_NAME
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite COME_FROM
except_handler else_suite come_froms
# Python 2.6 omits the LOAD_FAST DELETE_FAST below
# withas is allowed as a "from future" in 2.5

View File

@ -15,48 +15,43 @@ class Python26Parser(Python2Parser):
def p_try_except26(self, args):
"""
except_stmt ::= except_cond3 except_suite
except_cond1 ::= DUP_TOP expr COMPARE_OP
JUMP_IF_FALSE POP_TOP POP_TOP POP_TOP POP_TOP
except_cond3 ::= DUP_TOP expr COMPARE_OP
JUMP_IF_FALSE POP_TOP POP_TOP store POP_TOP
except_stmt ::= except_cond3 except_suite
except_cond1 ::= DUP_TOP expr COMPARE_OP
JUMP_IF_FALSE POP_TOP POP_TOP POP_TOP POP_TOP
except_cond3 ::= DUP_TOP expr COMPARE_OP
JUMP_IF_FALSE POP_TOP POP_TOP store POP_TOP
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
come_from_pop END_FINALLY come_froms
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
come_from_pop END_FINALLY come_froms
try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY
come_froms
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY
come_froms
try_middle ::= jmp_abs COME_FROM except_stmts
POP_TOP END_FINALLY
except_handler ::= jmp_abs COME_FROM except_stmts
POP_TOP END_FINALLY
try_middle ::= jmp_abs COME_FROM except_stmts
END_FINALLY JUMP_FORWARD
except_handler ::= jmp_abs COME_FROM except_stmts
END_FINALLY JUMP_FORWARD
# Sometimes we don't put in COME_FROM to the next statement
# like we do in 2.7. Perhaps we should?
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite COME_FROM
except_handler else_suite COME_FROM
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
except_suite ::= c_stmts_opt JUMP_FORWARD come_from_pop
except_suite ::= c_stmts_opt JUMP_FORWARD POP_TOP
except_suite ::= c_stmts_opt jmp_abs come_from_pop
# Python 3 also has this.
come_froms ::= come_froms COME_FROM
come_froms ::= COME_FROM
except_suite ::= c_stmts_opt JUMP_FORWARD come_from_pop
except_suite ::= c_stmts_opt JUMP_FORWARD POP_TOP
except_suite ::= c_stmts_opt jmp_abs come_from_pop
# This is what happens after a jump where
# we start a new block. For reasons I don't fully
# understand, there is also a value on the top of the stack
come_from_pop ::= COME_FROM POP_TOP
come_froms_pop ::= come_froms POP_TOP
come_froms_pop ::= come_froms POP_TOP
"""
# In contrast to Python 2.7, Python 2.6 has a lot of
@ -86,7 +81,7 @@ class Python26Parser(Python2Parser):
# COME_FROM_LOOP, but in <= 2.6 we don't distinguish
# this
cf_jb_cf_pop ::= _come_from JUMP_BACK come_froms POP_TOP
cf_jb_cf_pop ::= _come_froms JUMP_BACK come_froms POP_TOP
bp_come_from ::= POP_BLOCK COME_FROM
jb_bp_come_from ::= JUMP_BACK bp_come_from
@ -137,7 +132,7 @@ class Python26Parser(Python2Parser):
while1stmt ::= SETUP_LOOP l_stmts JUMP_BACK COME_FROM
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_from
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_froms
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop bp_come_from
whilestmt ::= SETUP_LOOP testexpr return_stmts POP_BLOCK COME_FROM
@ -179,7 +174,7 @@ class Python26Parser(Python2Parser):
jmp_true_then ::= JUMP_IF_TRUE THEN POP_TOP
while1stmt ::= SETUP_LOOP return_stmts COME_FROM
for_block ::= return_stmts _come_from
for_block ::= return_stmts _come_froms
"""
def p_comp26(self, args):
@ -206,7 +201,7 @@ class Python26Parser(Python2Parser):
comp_body ::= gen_comp_body
for_block ::= l_stmts_opt _come_from POP_TOP JUMP_BACK
for_block ::= l_stmts_opt _come_froms POP_TOP JUMP_BACK
# Make sure we keep indices the same as 2.7
setup_loop_lf ::= SETUP_LOOP LOAD_FAST
@ -242,11 +237,11 @@ class Python26Parser(Python2Parser):
and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP
# compare_chained is like x <= y <= z
compare_chained ::= expr compare_chained1 ROT_TWO COME_FROM POP_TOP _come_from
compare_chained ::= expr compare_chained1 ROT_TWO COME_FROM POP_TOP _come_froms
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
jmp_false compare_chained1 _come_from
jmp_false compare_chained1 _come_froms
compare_chained1 ::= expr DUP_TOP ROT_THREE COMPARE_OP
jmp_false compare_chained2 _come_from
jmp_false compare_chained2 _come_froms
return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP
stmt ::= conditional_lambda
conditional_lambda ::= expr jmp_false_then expr return_if_lambda

View File

@ -48,7 +48,7 @@ class Python27Parser(Python2Parser):
COME_FROM_FINALLY suite_stmts_opt END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite COME_FROM
except_handler else_suite COME_FROM
except_stmt ::= except_cond2 except_suite
@ -61,9 +61,6 @@ class Python27Parser(Python2Parser):
def p_jump27(self, args):
"""
come_froms ::= come_froms COME_FROM
come_froms ::= COME_FROM
iflaststmtl ::= testexpr c_stmts_opt
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms
@ -100,7 +97,7 @@ class Python27Parser(Python2Parser):
# assert condition, expr
assert2 ::= assert_expr jmp_true LOAD_ASSERT expr CALL_FUNCTION_1 RAISE_VARARGS_1
for_block ::= return_stmts _come_from
for_block ::= return_stmts _come_froms
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt
POP_BLOCK LOAD_CONST COME_FROM_WITH
@ -112,7 +109,7 @@ class Python27Parser(Python2Parser):
while1stmt ::= SETUP_LOOP return_stmts bp_come_from
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_from
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK POP_BLOCK
else_suite COME_FROM
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK

View File

@ -156,10 +156,10 @@ class Python3Parser(PythonParser):
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD
else_suite opt_come_from_except
ifelsestmt ::= testexpr c_stmts_opt jump_forward_else
else_suite _come_from
else_suite _come_froms
# ifelsestmt ::= testexpr c_stmts_opt jump_forward_else
# passstmt _come_from
# passstmt _come_froms
ifelsestmtc ::= testexpr c_stmts_opt JUMP_ABSOLUTE else_suitec
ifelsestmtc ::= testexpr c_stmts_opt jump_absolute_else else_suitec
@ -177,7 +177,7 @@ class Python3Parser(PythonParser):
# COME_FROM targets from the wrong places
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle opt_come_from_except
except_handler opt_come_from_except
# this is nested inside a try_except
tryfinallystmt ::= SETUP_FINALLY suite_stmts_opt
@ -185,27 +185,28 @@ class Python3Parser(PythonParser):
COME_FROM_FINALLY suite_stmts_opt END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite come_from_except_clauses
except_handler else_suite come_from_except_clauses
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite come_froms
except_handler else_suite come_froms
tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitec come_from_except_clauses
tryelsestmtc ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler else_suitec come_from_except_clauses
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suitel come_from_except_clauses
tryelsestmtl ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler else_suitel come_from_except_clauses
try_middle ::= jmp_abs COME_FROM except_stmts
END_FINALLY
try_middle ::= jmp_abs COME_FROM_EXCEPT except_stmts
END_FINALLY
except_handler ::= jmp_abs COME_FROM except_stmts
END_FINALLY
except_handler ::= jmp_abs COME_FROM_EXCEPT except_stmts
END_FINALLY
# FIXME: remove this
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM_EXCEPT
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM
except_handler ::= JUMP_FORWARD COME_FROM except_stmts
END_FINALLY COME_FROM_EXCEPT
except_stmts ::= except_stmts except_stmt
except_stmts ::= except_stmt
@ -267,10 +268,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_EXCEPT_CLAUSE
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY COME_FROM
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY COME_FROM_EXCEPT_CLAUSE
for_block ::= l_stmts_opt come_from_loops JUMP_BACK
for_block ::= l_stmts
@ -300,10 +301,9 @@ class Python3Parser(PythonParser):
def p_come_from3(self, args):
"""
opt_come_from_except ::= COME_FROM_EXCEPT
opt_come_from_except ::= come_froms
opt_come_from_except ::= _come_froms
opt_come_from_except ::= come_from_except_clauses
come_froms ::= COME_FROM*
come_from_except_clauses ::= COME_FROM_EXCEPT_CLAUSE+
come_from_loops ::= COME_FROM_LOOP*
"""
@ -334,7 +334,7 @@ class Python3Parser(PythonParser):
return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST
stmt ::= whileTruestmt
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite _come_from
ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD else_suite _come_froms
"""
def p_loop_stmt3(self, args):

View File

@ -24,7 +24,7 @@ class Python30Parser(Python31Parser):
# In many ways Python 3.0 code generation is more like Python 2.6 than
# it is 2.7 or 3.1. So we have a number of 2.6ish (and before) rules below
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_froms POP_TOP COME_FROM
jmp_true ::= JUMP_IF_TRUE POP_TOP
jmp_false ::= JUMP_IF_FALSE POP_TOP

View File

@ -29,23 +29,23 @@ class Python32Parser(Python3Parser):
# jump_excepts. But in 3.3 we need them added
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle
except_handler
jump_excepts come_from_except_clauses
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts
END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite
jump_excepts come_from_except_clauses
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
except_handler else_suite
jump_excepts come_from_except_clauses
jump_excepts ::= jump_except+
jump_excepts ::= jump_except+
# Python 3.2+ has more loop optimization that removes
# JUMP_FORWARD in some cases, and hence we also don't
# see COME_FROM
_ifstmts_jump ::= c_stmts_opt
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_from
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD _come_froms
stmt ::= del_deref_stmt
del_deref_stmt ::= DELETE_DEREF
@ -65,11 +65,11 @@ class Python32Parser(Python3Parser):
def add_custom_rules(self, tokens, customize):
self.remove_rules("""
try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
try_middle ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM_EXCEPT
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts END_FINALLY COME_FROM_EXCEPT_CLAUSE
try_middle ::= jmp_abs COME_FROM except_stmts END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK try_middle else_suite come_from_except_clauses
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM
except_handler ::= JUMP_FORWARD COME_FROM except_stmts END_FINALLY COME_FROM_EXCEPT
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_stmts END_FINALLY COME_FROM_EXCEPT_CLAUSE
except_handler ::= jmp_abs COME_FROM except_stmts END_FINALLY
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK except_handler else_suite come_from_except_clauses
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK NOP COME_FROM_LOOP
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK NOP COME_FROM_LOOP
""")

View File

@ -22,7 +22,7 @@ class Python33Parser(Python32Parser):
# jump_excepts. But in 3.3 we need them added
try_except ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle
except_handler
jump_excepts come_from_except_clauses
"""

View File

@ -65,14 +65,14 @@ class Python36Parser(Python35Parser):
# In 3.6+, A sequence of statements ending in a RETURN can cause
# JUMP_FORWARD END_FINALLY to be omitted from try middle
except_return ::= POP_TOP POP_TOP POP_TOP return_stmts
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_return
except_return ::= POP_TOP POP_TOP POP_TOP return_stmts
except_handler ::= JUMP_FORWARD COME_FROM_EXCEPT except_return
# Try middle following a return_stmts
try_middle36 ::= COME_FROM_EXCEPT except_stmts END_FINALLY
except_handler36 ::= COME_FROM_EXCEPT except_stmts END_FINALLY
stmt ::= try_except36
try_except36 ::= SETUP_EXCEPT return_stmts try_middle36 opt_come_from_except
stmt ::= try_except36
try_except36 ::= SETUP_EXCEPT return_stmts except_handler36 opt_come_from_except
"""
def add_custom_rules(self, tokens, customize):

View File

@ -1037,14 +1037,17 @@ class Scanner2(Scanner):
elif not (code[label] == self.opc.POP_TOP and
code[self.prev[label]] == self.opc.RETURN_VALUE):
# In Python < 2.7, don't add a COME_FROM, for:
# RETURN_VALUE POP_TOP .. END_FINALLY
# ~RETURN_VALUE POP_TOP .. END_FINALLY
# or:
# RETURN_VALUE POP_TOP .. POP_TOP END_FINALLY
skip_come_from = False
if self.version <= 2.6:
skip_come_from = (code[offset+3] == self.opc.END_FINALLY or
(code[offset+3] == self.opc.POP_TOP
and code[offset+4] == self.opc.END_FINALLY))
# ~RETURN_VALUE POP_TOP .. POP_TOP END_FINALLY
skip_come_from = (code[offset+3] == self.opc.END_FINALLY or
(code[offset+3] == self.opc.POP_TOP
and code[offset+4] == self.opc.END_FINALLY))
# The below is for special try/else handling
if skip_come_from and op == self.opc.JUMP_FORWARD:
skip_come_from = False
if not skip_come_from:
# FIXME: rocky: I think we need something like this...
if offset not in set(self.ignore_if):

View File

@ -353,6 +353,7 @@ class SourceWalker(GenericASTTraversal, object):
'testtrue_then': ( 'not %p', (0, 22) ),
})
if 2.4 <= version <= 2.6:
TABLE_DIRECT.update({
'comp_for': ( ' for %c in %c', 3, 1 ),
@ -1901,6 +1902,10 @@ class SourceWalker(GenericASTTraversal, object):
node[-2][0].kind = 'unpack_w_parens'
self.default(node)
# except_cond3 is only in Python <= 2.6
n_except_cond3 = n_except_cond2
def template_engine(self, entry, startnode):
"""The format template interpetation engine. See the comment at the
beginning of this module for the how we interpret format