More 2.6 control flow logix futzing

This commit is contained in:
rocky
2018-05-09 11:12:16 -04:00
parent 24ccc16701
commit 80b68af2d3
3 changed files with 31 additions and 6 deletions

Binary file not shown.

View File

@@ -0,0 +1,17 @@
# From 2.6 test_datetime.py
# Bug is in parsing (x is 0 or x is 1) and (y is 5 or y is 2)
# correctly.
# This code is RUNNABLE!
result = []
for y in (1, 2, 10):
x = cmp(1, y)
if (x is 0 or x is 1) and (y is 5 or y is 2):
expected = 10
elif y is 2:
expected = 2
else:
expected = 3
result.append(expected)
assert result == [10, 2, 3]

View File

@@ -264,10 +264,11 @@ class Python26Parser(Python2Parser):
dict ::= BUILD_MAP kvlist
kvlist ::= kvlist kv3
expr ::= conditional_not
conditional_not ::= expr jmp_true expr _jump COME_FROM POP_TOP expr COME_FROM
# Note: preserve positions 0 2 and 4 for semantic actions
conditional_not ::= expr jmp_true expr jf_cf_pop expr COME_FROM
conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt
expr ::= conditional_not
conditional ::= expr jmp_false expr jf_cf_pop expr come_from_opt
and ::= expr JUMP_IF_FALSE POP_TOP expr JUMP_IF_FALSE POP_TOP
# compare_chained is like x <= y <= z
@@ -322,7 +323,8 @@ class Python26Parser(Python2Parser):
WITH_CLEANUP END_FINALLY
""")
super(Python26Parser, self).customize_grammar_rules(tokens, customize)
# self.check_reduce['and'] = 'AST'
if self.version >= 2.6:
self.check_reduce['and'] = 'AST'
self.check_reduce['assert_expr_and'] = 'AST'
self.check_reduce['list_for'] = 'AST'
self.check_reduce['try_except'] = 'tokens'
@@ -347,14 +349,20 @@ class Python26Parser(Python2Parser):
# For now, we won't let the 2nd 'expr' be a "conditional_not"
# However in < 2.6 where we don't have if/else expression it *can*
# be.
if self.version >= 2.6 and ast[2][0] == 'conditional_not':
if ast[2][0] == 'conditional_not':
return True
test_index = last
while tokens[test_index].kind == 'COME_FROM':
test_index += 1
if tokens[test_index].kind.startswith('JUMP_IF'):
return False
# Test that jmp_false jumps to the end of "and"
# or that it jumps to the same place as the end of "and"
jmp_false = ast[1][0]
jmp_target = jmp_false.offset + jmp_false.attr + 3
return not (jmp_target == tokens[last].offset or
return not (jmp_target == tokens[test_index].offset or
tokens[last].pattr == jmp_false.pattr)
elif rule == (
'list_for',