Дизайн компилятора - восстановление после ошибок

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

  • Lexical : неверно набрано имя некоторого идентификатора

  • Syntactical : отсутствует точка с запятой или несбалансированные круглые скобки

  • Semantical : несовместимое присвоение значений

  • Logical : код недоступен, бесконечный цикл

Существует четыре распространенных стратегии исправления ошибок, которые могут быть реализованы в анализаторе для устранения ошибок в коде.

Панический режим

Когда синтаксический анализатор обнаруживает ошибку в любом месте оператора, он игнорирует остальную часть оператора, не обрабатывая ввод из ошибочного ввода до разделителя, такого как точка с запятой. Это самый простой способ исправления ошибок, а также он не позволяет синтаксическому анализатору создавать бесконечные циклы.

Режим заявления

Когда синтаксический анализатор обнаруживает ошибку, он пытается принять меры по исправлению, чтобы остальные входные данные оператора позволяли синтаксическому анализатору выполнить синтаксический анализ заранее. Например, вставка отсутствующей точки с запятой, замена запятой точкой с запятой и т. Д. Разработчики парсеров должны быть осторожны здесь, потому что одно неверное исправление может привести к бесконечному циклу.

Производство ошибок

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

Глобальная коррекция

Синтаксический анализатор рассматривает текущую программу в целом и пытается выяснить, для чего предназначена программа, и пытается найти для нее наиболее близкое соответствие, что не вызывает ошибок. Когда подается ошибочный ввод (оператор) X, он создает дерево синтаксического анализа для ближайшего безошибочного оператора Y. Это может позволить синтаксическому анализатору внести минимальные изменения в исходный код, но из-за сложности (время и пространство) эта стратегия пока не реализована на практике.

Абстрактные синтаксические деревья

Компилятору нелегко проанализировать представления дерева синтаксического анализа, поскольку они содержат больше деталей, чем фактически необходимо. В качестве примера возьмем следующее дерево синтаксического анализа:

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

Абстрактное дерево можно представить в виде:

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