Восстановление после синтаксических ошибок

Одним из простейших методов восстановления после ошибки при LR(1)-анализе является следующий. При синтаксической ошибке просматриваем магазин от верхушки, пока не найдем состояние s с переходом на выделенный нетерминал A. Затем сканируются входные символы, пока не будет найден такой, который допустим после A. В этом случае на верхушку магазина помещается состояние Goto[s, A] и разбор продолжается. Для нетерминала A может иметься несколько таких вариантов. Обычно A - это нетерминал, представляющий одну из основных конструкций языка, например оператор.

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

Варианты LR-анализаторов

Часто построенные таблицы для LR(1)-анализатора оказываются довольно большими. Поэтому при практической реализации используются различные методы их сжатия. С другой стороны, часто оказывается, что при построении для языка синтаксического анализатора типа «сдвиг-свертка» достаточно более простых методов. Некоторые из этих методов базируются на основе LR(1)-анализаторов.

Одним из способов такого упрощения является LR(0)-анализ - частный случая LR-анализа, когда ни при построении таблиц, ни при анализе не учитывается аванцепочка.

Еще одним вариантом LR-анализа являются так называемые SLR(1)-анализаторы (Simple LR(1)). Они строятся следующим образом. Пусть C = {I0, I1, ..., In} - набор множеств допустимых LR(0)-ситуаций. Состояния анализатора соответствуют Ii. Функции действий и переходов анализатора определяются следующим образом.

  • Если [A Восстановление после синтаксических ошибок - student2.ru u.av] Восстановление после синтаксических ошибок - student2.ru Ii и goto(Ii, a) = Ij, то определим Action[i, a] = shift j.
  • Если [A Восстановление после синтаксических ошибок - student2.ru u.] Восстановление после синтаксических ошибок - student2.ru Ii, то определим Action[i, a] = reduce A Восстановление после синтаксических ошибок - student2.ru u для всех a Восстановление после синтаксических ошибок - student2.ru FOLLOW(A), A Восстановление после синтаксических ошибок - student2.ru S'.
  • Если [S' Восстановление после синтаксических ошибок - student2.ru S.] Восстановление после синтаксических ошибок - student2.ru Ii, то определим Action[i, $] = accept.
  • Если goto(Ii, A) = Ij, где A Восстановление после синтаксических ошибок - student2.ru N, то определим Goto[i, A] = j.
  • Остальные входы для функций Action и Goto определим как error.
  • Начальное состояние соответствует множеству ситуаций, содержащему ситуацию [S' Восстановление после синтаксических ошибок - student2.ru .S].

Распространенным вариантом LR(1)-анализа является также LALR(1)-анализ. Он основан на объединении (слиянии) некоторых таблиц. Назовем ядром множества LR(1)-ситуаций множество их первых компонент (т.е. во множестве ситуаций не учитываются аванцепочки). Объединим все множества ситуаций с одинаковыми ядрами, а в качестве аванцепочек возьмем объединение аванцепочек. Функции Action и Goto строятся очевидным образом. Если функция Action таким образом построенного анализатора не имеет конфликтов, то он называется LALR(1)-анализатором (LookAhead LR(1)).

Наши рекомендации