как дать действие для каждого правила bison

Я пытаюсь сделать небольшой компилятор, используя flex и bison, но я не понимал, как выполнить действие для каждого правила.

моя грамматика такая:

     %union{
            std::string *s;
    };

%start program
%type <s> expr

%token <s> KEYWORD
%token <s> VARIABLE

%%

program : KEYWORD {std::cout << "A"; } 
| KEYWORD VARIABLE {std::cout << "B"; }

Регулярное выражение переменной [a-zA-Z0-9]

"шапки" - мое ключевое слово

если я ввожу ввод как «caps lock» (caps = KEYWORD и lock = VARIABLE), я получаю вывод как «B»

если я ввожу ввод в виде заглавных букв, он ждет, пока я не введу следующее слово, и после ввода любого следующего слова он печатает «Ошибка синтаксиса», если следующий ввод - заглавные буквы.

Проблема в том, что он ждет, пока не будет дан следующий ввод для печати A, и он все еще печатает A, если присутствует ошибка с синтаксической ошибкой.

Я не понял, что с ним не так, может кто-нибудь найти в нем ошибку.


person Jeevansai Jinne    schedule 15.04.2017    source источник
comment
Итак, вы печатаете А, но не Б? Это означает, что вы идентифицируете вещи как ключевые слова, но, по-видимому, не как переменные. Проблема не в грамматике — проблема в лексическом анализаторе, который вы не показали. Вам следует подумать о добавлении новой строки в печать. (Также необычно — как в COBOL — использовать - в качестве символа в именах переменных. Вы имели в виду _ между Z и 0?) Убедились ли вы, что можете включить диагностическую печать в лексическом анализаторе, чтобы вы могли видеть поток токенов? вернулся к грамматике? В долгосрочной перспективе это облегчило бы жизнь, если бы вы могли.   -  person Jonathan Leffler    schedule 15.04.2017
comment
как включить диагностическую печать в flex и я ничего не печатаю в лексическом анализаторе как добавить новую строку   -  person Jeevansai Jinne    schedule 15.04.2017
comment
Вы должны предоставить управление в коде Flex. Он не предоставляется по умолчанию. Однако возможность видеть, что возвращает лексический анализатор, часто может помочь при отладке грамматики.   -  person Jonathan Leffler    schedule 15.04.2017
comment
токены идеально разделены во flex, я нашел это, напечатав на стандартный вывод для того же ввода   -  person Jeevansai Jinne    schedule 15.04.2017
comment
В ПОРЯДКЕ. Я не программирую на Bison C++. или Flex C++, поэтому мне не нужно преобразовывать ваши фрагменты в MCVE (минимальный воспроизводимый пример). Если повезет, позже появится кто-то, кто может оказать вам другую помощь. Если вы решите опубликовать настоящий компилируемый MCVE, дайте мне знать (мое внимание должен привлечь комментарий к @JonathanLeffler). Я рад слышать, что ваш токенизатор работает отлично, но я боюсь, что увижу — значит поверю.   -  person Jonathan Leffler    schedule 15.04.2017
comment
я хочу извиниться, я ошибся с некоторыми ошибками, вопрос теперь отредактирован, на самом деле я не знаю, почему он работает сейчас   -  person Jeevansai Jinne    schedule 15.04.2017


Ответы (1)


Bison требуется токен «конец ввода», чтобы отметить конец ввода и вернуть успешный синтаксический анализ. Обычно вы даете ему этот токен при чтении EOF (это то, что будет делать lex/flex). Поэтому, если вы вводите EOF (как правило, нажимая ctrlD или ctrlZ) после ввода, он должен Работа.

person Chris Dodd    schedule 15.04.2017
comment
как мне остановить bison от повторения несовпадающего ввода, такого как пробел и новая строка, и почему он повторяет только пробел и новую строку и дает синтаксическую ошибку для других несовпадающих строк ascii. - person Jeevansai Jinne; 16.04.2017
comment
@JeevansaiJinne: Bison не повторяет непревзойденный ввод; это работа Флекса. У него есть правило по умолчанию, которое отображает совпадающий текст, который не захвачен никаким другим правилом (приблизительно .+ { ECHO; }). - person Jonathan Leffler; 16.04.2017
comment
Как мне напечатать пробел в бизоне, это печать адреса - person Jeevansai Jinne; 16.04.2017
comment
@JeevansaiJinne: сам bison просто сопоставляет последовательности токенов с продуктами и запускает связанные действия — если вы хотите напечатать пробел, напечатайте его в действии. Как заметил Джонатан Леффлер, flex (и lex) будут отображать нераспознанные символы; если вы этого не хотите, рекомендуется использовать опцию flex -s (или --nodefault), которая заставит его помечать ошибку для любого необработанного/неожиданного ввода. - person Chris Dodd; 16.04.2017
comment
что я хотел спросить, так это то, что я присваиваю любое значение токена строковой переменной в flex, если я назначаю пробелы, соответствующие строке, и пытаюсь напечатать его в бизоне, это печатает адрес - person Jeevansai Jinne; 16.04.2017
comment
@JeevansaiJinne: тогда вы, вероятно, назначаете и печатаете указатель, а не строку - скопируйте строку и распечатайте ее как строку, а не указатель, если вам нужна строка. Ничего общего с flex или bison как таковыми — просто код C++, который у вас есть в ваших действиях. - person Chris Dodd; 17.04.2017