Это не значит, что ply не считает символы новой строки.Он их никогда не видит, потому что вы вызываете его несколько раз, используя input()
.
Из документов Python (выделение добавлено):
input ([prompt])
Если аргумент подсказки присутствует, он записывается в стандартный вывод без завершающей строки.Затем функция читает строку из ввода, преобразует ее в строку (, удаляя завершающий символ новой строки ), и возвращает ее.
Обычно lex.lex
используется для
Кроме того, вы печатаете
... + str(tok.lineno)
вместо
... + str(lexer.lineno)
После токенизации последнего токена lex.lex
возвращает None
, так что вы можете ожидать tok
будет Null
, когда ваш цикл завершится, и поэтому попытка извлечь его атрибут lineno
будет ошибкой.(Однако в вашем случае это происходит только в том случае, если строка, которую вы только что попытались токенизировать, была пустой, потому что вы используете только первый токен в каждой строке.) Вы хотите, чтобы количество строк записывалось в объект лексера, то есть количество, которое вы обновляете вваше действие.
Если вы хотите работать с целым файлом (что обычно для синтаксических анализаторов, кроме построчных калькуляторов), вам необходимо прочитать все содержимое файла (или стандартный ввод).в зависимости от обстоятельств).Для неинтерактивного использования вы обычно делаете это с функцией read
файлового объекта.Если вы хотите протестировать свой лексер, вы должны использовать тот факт, что функция lex
реализует итерационный протокол Python, поэтому она будет работать в операторе for
.Таким образом, ваш основной цикл будет выглядеть примерно так:
import sys
lexer.input(sys.stdin.read())
for tok in lexer:
# Update counts
, и вы завершите ввод, введя символ конца файла в начале строки (control-D в Linux или control-Z вWindows).
Лично я бы реализовал подсчет типов токенов с помощью defaultdict
:
from collections import defaultdict
counts = defaultdict(int)
for tok in lexer:
counts[tok.type] += 1
for type, count in counts.items():
print ("Number of %s's: %d\n" % (type, count))
# Or: print('\n'.join("Number of %s's: %d\n" % (type, count) for type, count in counts.items())
print ("Number of lines: %d\n" % lexer.lineno)