Как указано в комментариях, почти наверняка PROGRAM
начинает распознаваться как токен и передается парсеру. Однако почти во всех случаях анализатор немедленно запросит другой токен, а следующий символ во входной последовательности - это пробел, которому соответствует последнее правило. Это правило печатает сообщение об ошибке и вызывает exit()
, завершая работу приложения. (Как правило, это не очень хорошая идея, но я предполагаю, что это всего лишь тестовая программа.) Так что это все, что вы получите.
Если вы укажете аргумент командной строки -d
при вызове (f) lex, тогда будет создан отладочный сканер, который сообщает о работе сканера, как он работает. Это очень простой способ увидеть, что происходит в вашем сканере. Bison также имеет режим отладки, как объяснено в руководстве по бизонам . Эти инструменты очень просты в использовании и рекомендуются к использованию.
Вот, например, быстрый тестовый стенд:
%{
#include <iostream>
#include <cstdlib>
class Parser {
public:
enum Token {
PROGRAM = 257,
PROGRAM_END, VARIABLES, INSTRUCTIONS, SKIP
};
};
%}
%option batch noyywrap yylineno c++
%%
PROGRAM return Parser::PROGRAM;
PROGRAM_END return Parser::PROGRAM_END;
VARIABLES: return Parser::VARIABLES;
INSTRUCTIONS: return Parser::INSTRUCTIONS;
SKIP return Parser::SKIP;
. {
std::cerr << lineno() << ": ERROR." << std::endl;
exit(1);
}
%%
int main() {
yyFlexLexer lexer{};
lexer.set_debug(1);
while(lexer.yylex() != 0) { }
return 0;
}
и примерный прогон:
$ g++ lex.yy.cc && ./a.out<<<"PROGRAM fst"
--(end of buffer or a NUL)
--accepting rule at line 14("PROGRAM")
--accepting rule at line 19(" ")
1: ERROR.
, который дает понять, что сканер сначала выдал токен PROGRAM
, прежде чем выйти из символа пробела.