Merge pull request #269 from rocky/if-elif-else-more

If elif else more
This commit is contained in:
R. Bernstein
2019-07-01 09:52:11 -04:00
committed by GitHub
4 changed files with 70 additions and 5 deletions

View File

@@ -152,11 +152,8 @@ class Python3Parser(PythonParser):
_ifstmts_jump ::= return_if_stmts
_ifstmts_jump ::= c_stmts_opt COME_FROM
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE
iflaststmt ::= testexpr c_stmts_opt JUMP_ABSOLUTE
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK COME_FROM_LOOP
iflaststmtl ::= testexpr c_stmts_opt JUMP_BACK POP_BLOCK
# These are used to keep parse tree indices the same
jump_forward_else ::= JUMP_FORWARD ELSE
@@ -182,6 +179,8 @@ class Python3Parser(PythonParser):
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
ifelsestmtl ::= testexpr c_stmts_opt cf_jump_back else_suitel
ifelsestmtl ::= testexpr c_stmts_opt continue else_suitel
cf_jump_back ::= COME_FROM JUMP_BACK
@@ -348,6 +347,8 @@ class Python3Parser(PythonParser):
def p_loop_stmt3(self, args):
"""
stmt ::= whileelsestmt2
for ::= SETUP_LOOP expr for_iter store for_block POP_BLOCK
COME_FROM_LOOP
@@ -363,6 +364,8 @@ class Python3Parser(PythonParser):
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt COME_FROM JUMP_BACK POP_BLOCK
COME_FROM_LOOP
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK JUMP_BACK
COME_FROM_LOOP
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
COME_FROM_LOOP
@@ -375,6 +378,9 @@ class Python3Parser(PythonParser):
whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
else_suitel COME_FROM_LOOP
whileelsestmt2 ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
else_suitel JUMP_BACK COME_FROM_LOOP
whileTruestmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK
COME_FROM_LOOP

View File

@@ -377,6 +377,7 @@ TABLE_DIRECT = {
'while1stmt': ( '%|while 1:\n%+%c%-\n\n', 1 ),
'while1elsestmt': ( '%|while 1:\n%+%c%-%|else:\n%+%c%-\n\n', 1, -2 ),
'whileelsestmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -2 ),
'whileelsestmt2': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-\n\n', 1, 2, -3 ),
'whileelselaststmt': ( '%|while %c:\n%+%c%-%|else:\n%+%c%-', 1, 2, -2 ),
# Note: Python 3.8+ changes this

View File

@@ -661,21 +661,33 @@ class SourceWalker(GenericASTTraversal, object):
if ..
elif ...
[else ...]
where appropriate
"""
else_suite = node[3]
n = else_suite[0]
old_stmts = None
if len(n) == 1 == len(n[0]) and n[0] == 'stmt':
n = n[0][0]
elif n[0].kind in ('lastc_stmt', 'lastl_stmt'):
n = n[0]
if n[0].kind in ('ifstmt', 'iflaststmt', 'ifelsestmtl'):
if n[0].kind in ('ifstmt', 'iflaststmt', 'iflaststmtl', 'ifelsestmtl', 'ifelsestmtc'):
# This seems needed for Python 2.5-2.7
n = n[0]
pass
pass
elif ( len(n) > 1 and 1 == len(n[0]) and n[0] == 'stmt'
and n[1].kind == "stmt" ):
else_suite_stmts = n[0]
if else_suite_stmts[0].kind not in ('ifstmt', 'iflaststmt', 'ifelsestmtl'):
if not preprocess:
self.default(node)
return
old_stmts = n
n = else_suite_stmts[0]
else:
if not preprocess:
self.default(node)
@@ -695,6 +707,18 @@ class SourceWalker(GenericASTTraversal, object):
elif n.kind in ('ifelsestmt', 'ifelsestmtc', 'ifelsestmtl'):
n.kind = 'elifelsestmt'
if not preprocess:
if old_stmts:
if n.kind == "elifstmt":
trailing_else = SyntaxTree("stmts", old_stmts[1:])
# We use elifelsestmtr because it has 3 nodes
elifelse_stmt = SyntaxTree(
'elifelsestmtr', [n[0], n[1], trailing_else])
node[3] = elifelse_stmt
pass
else:
# Other cases for n.kind may happen here
return
pass
self.default(node)
n_ifelsestmtc = n_ifelsestmtl = n_ifelsestmt