我在
python3.6中编写了一个解析器;我仍在尽可能地简化它,同时仍然产生错误:
def tokenize(expr):
for i in expr:
try:
yield int(i)
except ValueError:
yield i
def push_on_stream(obj, stream):
yield obj
yield from stream
class OpenBracket:
"just a token value, could have used Ellipsis"
pass
def parse_toks(tokstream):
result = []
leading_brak = False
for tok in tokstream:
if tok == OpenBracket:
leading_brak = True
elif tok == '(':
result.append(parse_toks(
push_on_stream(OpenBracket, tokstream)))
elif tok == ')':
if not leading_brak:
raise SyntaxError("Very bad ')'.")
break
else:
result.append(tok)
return sum(result)
def test(expr="12(34)21"):
tokens = tokenize(expr)
print( parse_toks(tokens) )
print(list(tokens))
test()
这个例子很简单;效果应该是添加字符串中的所有数字,包括括号中的数字.
tokenize()函数产生令牌,parse_tok()函数解析令牌流.如果它遇到一个开括号,它会递归(将OpenBracket推送到令牌流),这应该具有将括号中的数字作为单独的表达式处理,解析它并将结果添加到结果堆栈的效果.
当我解析代码时,例如在表达式“1(2)3”上,它立即在close括号后结束,返回3,实际上令牌流似乎已经结束.
但是,当我使用pdb运行它,并在parse_tok中的循环内设置断点时,我可以在处理’)’时小心步骤,程序正确返回6.
我认为这个bug与push_on_stream()中令牌流的屈服有关.
这是解释器中的错误吗?如果是这样有一个很好的解决方法?
我为python-3.6编写了它,但我也在python-3.7上在不同的机器上测试了它,结果相同.