Обработка ошибок в yacc
При чтении анализатором входного потока данные из этого потока могут не соответствовать ни одному правилу файла грамматики.
Анализатор должен обнаруживать подобные ошибки как можно раньше. Если в файле грамматики присутствует функция обработки ошибок, то с ее помощью можно запросить повторный ввод данных, пропустить данные с ошибкой или выполнить очистку и восстановление. Например, при обнаружении ошибки может потребоваться освобождение памяти, выделенной для дерева разбора, удаление или изменение записей таблицы символов и установка флагов для предотвращения дальнейшего разбора.
Если функция обработки ошибок не определена, то при обнаружении ошибки анализатор прекращает работу. Для дальнейшей обработки входного потока с целью обнаружения других ошибок необходимо перезапустить анализатор с той точки, в которой он сможет продолжить разбор входного потока. Одним из способов такого перезапуска является пропуск определенного числа лексем, следующих за лексемой, вызывавшей ошибку.
В команде yacc для обработки ошибок применяется специальная лексема error. Эту лексему помещают в раздел правил в тех местах, где может возникнуть ошибка и требуются специальные действия по ее обработке. Если ошибка возникает в таком месте, анализатор выполняет вместо обычного действия действие лексемы error.
| Макрокоманды | Описание |
|---|---|
| YYERROR | Вызывает обработку ошибки анализатором. |
| YYABORT | Анализатор возвращает значение 1. |
| YYACCEPT | Анализатор возвращает значение 0. |
| YYRECOVERING() | Возвращает 1, если была обнаружена синтаксическая ошибка и анализатор еще не завершил процесс исправления. |
Для того чтобы одна ошибка не приводила к возникновению нескольких сообщений об ошибках, анализатор остается в состоянии ошибки до те пор, пока он не обработает три лексемы, следующие за лексемой, вызвавшей ошибку. Если в течение этого времени возникнет еще одна ошибка, анализатор пропустит соответствующую лексему без выдачи сообщения.
stat : error ';'задает режим обработки, при котором анализатор будет пропускать лексему с ошибкой и все последующие лексемы до символа точки с запятой. Все лексемы, начиная с лексемы, в которой встретилась ошибка, и до точки с запятой, пропускаются. После обнаружения точки с запятой анализатор редуцирует это правило и выполняет установленные действия по очистке.
Исправление ошибок
input : error '\n'
{
printf(" Введите последнюю строку еще раз: " );
}
input
{
$$ = $4;
}
;yyerrok;Этот оператор переводит анализатор в обычное состояние. Процедура исправления ошибок с этим оператором выглядит так:
input : error '\n'
{
yyerrok;
printf(" Введите последнюю строку еще раз: " );
}
input
{
$$ = $4;
}
;Очистка следующей лексемы
yyclearin ;