Grammar "COME_FROM"_from cleanups ...

tryelse constructs in 2.x fixed up
_come_from -> _come_froms (COME_FROM*)
consolidate come_froms rule into sincle parser.py

sync unit/test_grammar.py
This commit is contained in:
rocky
2017-12-03 05:04:06 -05:00
parent 21a8726a47
commit c90210c063
9 changed files with 39 additions and 43 deletions

View File

@@ -18,12 +18,12 @@ class TestGrammar(unittest.TestCase):
(lhs, rhs, tokens,
right_recursive, dup_rhs) = p.check_sets()
expect_lhs = set(['expr1024', 'pos_arg'])
unused_rhs = set(['build_list', 'call_function', 'mkfunc',
unused_rhs = set(['list', 'call', 'mkfunc',
'mklambda',
'unpack',])
expect_right_recursive = frozenset([('designList',
('designator', 'DUP_TOP', 'designList'))])
('store', 'DUP_TOP', 'designList'))])
expect_lhs.add('kwarg')
self.assertEqual(expect_lhs, set(lhs))

View File

@@ -31,7 +31,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',
@@ -304,9 +304,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
@@ -358,19 +360,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):
@@ -493,7 +495,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

@@ -33,7 +33,7 @@ class Python25Parser(Python26Parser):
store ::= STORE_NAME
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
try_middle else_suite COME_FROM
try_middle 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

@@ -47,16 +47,11 @@ class Python26Parser(Python2Parser):
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
# 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
"""
# 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

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

@@ -154,10 +154,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
@@ -298,10 +298,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*
"""
@@ -332,7 +331,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

@@ -23,7 +23,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

@@ -43,7 +43,7 @@ class Python32Parser(Python3Parser):
# 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

View File

@@ -1041,14 +1041,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):