Flex не определяет, когда вернется сканер (за исключением правила EOF по умолчанию).Сканер, который он создает, выполняет лексические действия в цикле, пока какое-либо действие не вернется.Так что вам решать, как вы хотите структурировать свой сканер.
Однако классическая модель обработки yyparse / yylex состоит из парсера, вызывающего yylex()
каждый раз, когда ему нужен новый токен.Поэтому он ожидает, что yylex()
немедленно вернется, как только найдет токен.
В вашем первом примере кода нет парсера, и действие сканера ограничено распечаткой токена.Хотя пример совершенно правильный, полагаясь на цикл сканера для многократного выполнения действий, я бы предпочел вторую модель, даже если вы (пока) не намерены добавлять парсер, потому что это облегчит разделение обработки токена отгенерация токенов.
Это не значит, что каждое лексическое действие будет содержать оператор return.Некоторые лексические шаблоны соответствуют не токенам (например, комментарии и пробелы), и соответствующее действие, скорее всего, ничего не изменит (кроме возможной записи входной позиции), так что сканер продолжит поиск токена для возврата.
(F) Сканеры lex нелегко превратить в сопрограммы, поэтому, если действительно требуется сопрограмма (например, для пошагового разбора асинхронного ввода), тогда может быть предпочтительнее другой инструмент.
Bisonдействительно дает возможность генерировать «синтаксический анализатор», в котором сканер вызывает анализатор каждый раз, когда находит токен, вместо возврата к анализатору.Но ни «push», ни традиционная «pull» модель не имеют ничего общего с сопрограммами, ИМХО, и использование слова для описания взаимодействия анализатора и сканера кажется мне неточным и бесполезным (хотя я очень уважаюавтор, которого вы цитируете.)