@@ -156,7 +156,13 @@ def p_stmt27(self, args):
156156
157157 while1stmt ::= SETUP_LOOP returns bp_come_from
158158 while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM
159+
159160 whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms
161+
162+ # Should this be JUMP_BACK+ ?
163+ # JUMP_BACK should all be to the same location
164+ whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK JUMP_BACK POP_BLOCK _come_froms
165+
160166 while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK POP_BLOCK
161167 else_suitel COME_FROM
162168 whileelsestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK
@@ -211,14 +217,17 @@ def customize_grammar_rules(self, tokens, customize):
211217 self .check_reduce ['list_if_not' ] = 'AST'
212218 self .check_reduce ['list_if' ] = 'AST'
213219 self .check_reduce ['conditional_true' ] = 'AST'
220+ self .check_reduce ['whilestmt' ] = 'tokens'
214221 return
215222
216223 def reduce_is_invalid (self , rule , ast , tokens , first , last ):
217224 invalid = super (Python27Parser ,
218225 self ).reduce_is_invalid (rule , ast ,
219226 tokens , first , last )
227+
220228 if invalid :
221229 return invalid
230+
222231 if rule == ('and' , ('expr' , 'jmp_false' , 'expr' , '\\ e_come_from_opt' )):
223232 # Test that jmp_false jumps to the end of "and"
224233 # or that it jumps to the same place as the end of "and"
@@ -249,6 +258,16 @@ def reduce_is_invalid(self, rule, ast, tokens, first, last):
249258 jmp_target = jmp_true .offset + jmp_true .attr + 3
250259 return not (jmp_target == tokens [last ].offset or
251260 tokens [last ].pattr == jmp_true .pattr )
261+
262+ elif (rule [0 ] == 'whilestmt' and
263+ rule [1 ][0 :- 2 ] ==
264+ ('SETUP_LOOP' , 'testexpr' , 'l_stmts_opt' ,
265+ 'JUMP_BACK' , 'JUMP_BACK' )):
266+ # Make sure that the jump backs all go to the same place
267+ i = last - 1
268+ while (tokens [i ] != 'JUMP_BACK' ):
269+ i -= 1
270+ return tokens [i ].attr != tokens [i - 1 ].attr
252271 # elif rule[0] == ('conditional_true'):
253272 # # FIXME: the below is a hack: we check expr for
254273 # # nodes that could have possibly been a been a Boolean.
0 commit comments