Синтаксическая ошибка Bison easy file
Я пытаюсь запустить этот.y файл
%{
#include <stdlib.h>
#include <stdio.h>
int yylex();
int yyerror();
%}
%start BEGIN
%%
BEGIN: 'a' | BEGIN 'a'
%%
int yylex(){
return getchar();
}
int yyerror(char* s){
fprintf(stderr, "*** ERROR: %s\n", s);
return 0;
}
int main(int argn, char **argv){
yyparse();
return 0;
}
Это простая программа в зубре, синтаксис мне кажется правильным, но всегда возникает проблема с синтаксической ошибкой... Спасибо за вашу помощь.
1 ответ
Функция лексера yylex
необходимо вернуть 0, чтобы указать конец ввода. Однако ваша реализация просто проходит через значение, возвращаемое getchar
, которые будут EOF
(обычно -1).
Кроме того, ваш ввод почти наверняка будет содержать символ новой строки, который также будет передаваться парсеру.
Поскольку парсер не распознает ни \n
ни EOF
, он выдает ошибку, когда получает один из них.
Как минимум, вам нужно будет изменить yylex
правильно ответить на конец ввода:
int yylex(void) {
int ch = getchar();
return (ch == EOF) ? 0 : ch;
}
Но вам все равно придется иметь дело с символами новой строки, либо обрабатывая их в своем лексере (возможно, игнорируя их или возвращая конец ввода ввода), либо обрабатывая их в вашей грамматике.
Обратите внимание, что парсеры, сгенерированные bison/yacc, всегда анализируют весь входной поток, а не только самую длинную последовательность, удовлетворяющую грамматике. Это может быть скорректировано с некоторой работой - см. Документацию для YYACCEPT
специальные действия - но стандартное поведение обычно является тем, что желательно при разборе.
Кстати, пожалуйста, используйте стандартные правила стилей в грамматике bison/yacc, чтобы избежать проблем и чтобы сбить с толку читателей. Обычно мы оставляем за собой UPPER_CASE
для терминальных символов, так как они также используются как константы времени компиляции в лексере. Нетерминалы обычно пишутся на lower_case
хотя некоторые предпочитают использовать CamelCase
, Для терминалов вам следует избегать использования имен, зарезервированных стандартной библиотекой (таких как EOF
) или (f) lex (BEGIN
) или бизон / як (END
). В руководствах есть списки зарезервированных имен.