Исправление ошибок бизонов
Я обнаружил, что могу использовать "ошибку" в правиле грамматики в качестве механизма восстановления после ошибок. Поэтому, если произошла ошибка, парсер должен отбросить текущую строку и возобновить разбор со следующей строки. Пример из руководства по бизонам для достижения этой цели может быть примерно таким:
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()
,