Синтаксическая ошибка 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). В руководствах есть списки зарезервированных имен.

Другие вопросы по тегам