Обработка ошибок довольно сложное дело, так как большинство ситуаций связано с семантикой. При обнаружении ошибок может понажобиться, например, освободить память для дерева разбора, удалить или изменить строки в таблице символов и, что чаще всего, установить некоторые флаги для подавления генерации выходной информации.
При обнаружении ошибок прекращение обработки обычно неприемлемо. Более полезным является продолжение просмотра для обнаружения возможных ошибок. Это ведет к необходимости повторного запуска распознавателя после ошибки. Существует общий класс алгоритмов для этих действий, который включает в себя отбрасывание из входной строки ряда лексем и попытки изменить состояние распознавателя для продолжения обработки.
Для того, чтобы пользователь мог управлять этим процессом, yacc предоставляет простое, но достаточно универсальное средство. Для обработки ошибок зарезервирована лексема с именем error. Это имя может использоваться в грамматических правилах: им отмечаются места, где может встретиться ошибка и где необходимо провести восстановление. Распознаватель выталкивает состояния из стека до тех пор, пока не найдет состояние, в котором error допустимо. Далее считается что error - очередная лексема, и выполняются соответствующие действия. Затем значение очередной лексемы устанавливается равным лексеме, вызвавшей ошибку. Если никаких других правил не указано, при обнраужении ошибки обработка прекращается.
Для предотвращения потока сообщений об ошибках распознаватель после обнаружения ошибки остается в этом состоянии, пока не будут прочитаны и обработаны три следующие лексемы. Если ошибка обнаружена в момент, когда распознаватель находится в состоянии обработки ошибок, сообщений не выводится и входная лексема удаляется. Рассмотрим в качестве примера правило:

stat: error

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

stat: error';'

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

input: error'0 {printf("Введите строку:"); }
input  {$$=$4;}

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

input: error'0
              { yyerrok;
                printf("Введите строку:"); }

                input
                {$$=$4;}
                ;

Как уже было сказано, лексема, прочитанная непосредственно после символа error, считается лексемой, содержащей ошибку. Иногда это неприемлемо, например, действие по обработке ошибок само может определить место возобновления обработки. В этом случае очередная лексема должна очищаться. Этого эффекта можно достичь, применяя в действии оператор yyclearin. Предположим, например, что действие после ошибки заключается в вызове написанной пользователем функции, пытающейся синхронизироваться и установить указатель на начало следующего правильного оператора. После ее вызова следующая возвращаемая yylex лексема будет скорее всего, первой лексемой правильного оператора. Старая неправильная лексема должна быть отброшена, и состояние ошибки должно быть отменено. Этого можно достичь следующими правилами:

stat: error
            { resynch();
              yyerrok;
              yyclearin; }

Нужно признать, что эти механизмы довольно негибки, но они в действительности позволяют выполнить эффективное восстановление после большинства ошибок. Более того, пользователь может получить управление для обработки ошибок другими участками программы.