Исправление ошибок бизонов

Я обнаружил, что могу использовать "ошибку" в правиле грамматики в качестве механизма восстановления после ошибок. Поэтому, если произошла ошибка, парсер должен отбросить текущую строку и возобновить разбор со следующей строки. Пример из руководства по бизонам для достижения этой цели может быть примерно таким:

stmts:
      exp
      |stmts exp
      | error '\n'

Но я не могу это использовать; потому что мне пришлось заставить flex игнорировать '\n' в моем сканнаре, чтобы выражение не ограничивалось выражением в одной строке. Как я могу заставить синтаксический анализатор - при обнаружении ошибки - продолжить синтаксический анализ следующей строки, учитывая, что нет специального символа (то есть точки с запятой), указывающего конец выражения, и нет маркера "новой строки"?

Спасибо..

1 ответ

Решение

Поскольку вы удалили маркер, использованный в примере, вам придется тянуть трюк, чтобы получить эквивалентный эффект.

Я думаю, что вы можете использовать это:

stmts:
      exp
    | stmts exp
    | error { eat_to_newline(); }

куда eat_to_newline() это функция в сканере (исходный файл), которая организует сброс любых сохраненных токенов и чтение до следующей новой строки.

extern void eat_to_newline(void);

void eat_to_newline(void)
{
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
}

Вероятно, это должно быть немного сложнее, но не намного сложнее. Возможно, вам придется использовать yyerrok; (и, как напоминает мне комментарий, yyclearin; тоже) после звонка eat_to_newline(),

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