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
This commit is contained in:
rocky
2017-12-03 05:10:59 -05:00
parent b1cdbe1656
commit 32f3d947bb
8 changed files with 37 additions and 41 deletions

View File

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

View File

@@ -33,7 +33,7 @@ class Python25Parser(Python26Parser):
store ::= STORE_NAME store ::= STORE_NAME
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK 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 # Python 2.6 omits the LOAD_FAST DELETE_FAST below
# withas is allowed as a "from future" in 2.5 # 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 JUMP_FORWARD POP_TOP
except_suite ::= c_stmts_opt jmp_abs come_from_pop 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 # This is what happens after a jump where
# we start a new block. For reasons I don't fully # we start a new block. For reasons I don't fully
# understand, there is also a value on the top of the stack # understand, there is also a value on the top of the stack
come_from_pop ::= COME_FROM POP_TOP 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 # 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 # COME_FROM_LOOP, but in <= 2.6 we don't distinguish
# this # 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 bp_come_from ::= POP_BLOCK COME_FROM
jb_bp_come_from ::= JUMP_BACK bp_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 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 l_stmts_opt jb_cf_pop bp_come_from
whilestmt ::= SETUP_LOOP testexpr return_stmts POP_BLOCK 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 jmp_true_then ::= JUMP_IF_TRUE THEN POP_TOP
while1stmt ::= SETUP_LOOP return_stmts COME_FROM while1stmt ::= SETUP_LOOP return_stmts COME_FROM
for_block ::= return_stmts _come_from for_block ::= return_stmts _come_froms
""" """
def p_comp26(self, args): def p_comp26(self, args):
@@ -206,7 +201,7 @@ class Python26Parser(Python2Parser):
comp_body ::= gen_comp_body 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 # Make sure we keep indices the same as 2.7
setup_loop_lf ::= SETUP_LOOP LOAD_FAST 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 and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP
# compare_chained is like x <= y <= z # 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 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 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 return_if_lambda ::= RETURN_END_IF_LAMBDA POP_TOP
stmt ::= conditional_lambda stmt ::= conditional_lambda
conditional_lambda ::= expr jmp_false_then expr return_if_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): def p_jump27(self, args):
""" """
come_froms ::= come_froms COME_FROM
come_froms ::= COME_FROM
iflaststmtl ::= testexpr c_stmts_opt iflaststmtl ::= testexpr c_stmts_opt
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms _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 return_stmts bp_come_from
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK 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 while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK POP_BLOCK
else_suite COME_FROM else_suite COME_FROM
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK 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 ifelsestmt ::= testexpr c_stmts_opt JUMP_FORWARD
else_suite opt_come_from_except else_suite opt_come_from_except
ifelsestmt ::= testexpr c_stmts_opt jump_forward_else ifelsestmt ::= testexpr c_stmts_opt jump_forward_else
else_suite _come_from else_suite _come_froms
# ifelsestmt ::= testexpr c_stmts_opt jump_forward_else # 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_suitec
ifelsestmtc ::= testexpr c_stmts_opt jump_absolute_else else_suitec ifelsestmtc ::= testexpr c_stmts_opt jump_absolute_else else_suitec
@@ -300,10 +300,9 @@ class Python3Parser(PythonParser):
def p_come_from3(self, args): def p_come_from3(self, args):
""" """
opt_come_from_except ::= COME_FROM_EXCEPT 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 opt_come_from_except ::= come_from_except_clauses
come_froms ::= COME_FROM*
come_from_except_clauses ::= COME_FROM_EXCEPT_CLAUSE+ come_from_except_clauses ::= COME_FROM_EXCEPT_CLAUSE+
come_from_loops ::= COME_FROM_LOOP* come_from_loops ::= COME_FROM_LOOP*
""" """
@@ -334,7 +333,7 @@ class Python3Parser(PythonParser):
return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST return_closure ::= LOAD_CLOSURE RETURN_VALUE RETURN_LAST
stmt ::= whileTruestmt 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): 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 # 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 # 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_true ::= JUMP_IF_TRUE POP_TOP
jmp_false ::= JUMP_IF_FALSE POP_TOP jmp_false ::= JUMP_IF_FALSE POP_TOP

View File

@@ -45,7 +45,7 @@ class Python32Parser(Python3Parser):
# JUMP_FORWARD in some cases, and hence we also don't # JUMP_FORWARD in some cases, and hence we also don't
# see COME_FROM # see COME_FROM
_ifstmts_jump ::= c_stmts_opt _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 stmt ::= del_deref_stmt
del_deref_stmt ::= DELETE_DEREF del_deref_stmt ::= DELETE_DEREF

View File

@@ -1037,14 +1037,17 @@ class Scanner2(Scanner):
elif not (code[label] == self.opc.POP_TOP and elif not (code[label] == self.opc.POP_TOP and
code[self.prev[label]] == self.opc.RETURN_VALUE): code[self.prev[label]] == self.opc.RETURN_VALUE):
# In Python < 2.7, don't add a COME_FROM, for: # In Python < 2.7, don't add a COME_FROM, for:
# RETURN_VALUE POP_TOP .. END_FINALLY # ~RETURN_VALUE POP_TOP .. END_FINALLY
# or: # or:
# RETURN_VALUE POP_TOP .. POP_TOP END_FINALLY # ~RETURN_VALUE POP_TOP .. POP_TOP END_FINALLY
skip_come_from = False skip_come_from = (code[offset+3] == self.opc.END_FINALLY or
if self.version <= 2.6: (code[offset+3] == self.opc.POP_TOP
skip_come_from = (code[offset+3] == self.opc.END_FINALLY or and code[offset+4] == self.opc.END_FINALLY))
(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: if not skip_come_from:
# FIXME: rocky: I think we need something like this... # FIXME: rocky: I think we need something like this...
if offset not in set(self.ignore_if): if offset not in set(self.ignore_if):