Я написал парсер в 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", он сразу заканчивается после закрывающей скобки, возвращая 3 иНа самом деле поток токенов, похоже, закончился.
Когда я запускаю его, используя pdb, и устанавливаю точки останова внутри цикла в parse_tok, я могу осторожно выполнить шаг, когда он обрабатывает ')', и программа корректно возвращает 6 .
Я думаю, что ошибка связана с выходом из потока токенов в push_on_stream ().
Это ошибка в интерпретаторе?Если да, то есть ли хороший обходной путь?
Я написал его для python-3.6, но я также протестировал его на python-3.7 на другой машине с тем же результатом.