Проект компилятора - Восстановление после ошибок

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

  • Лексический : имя некоторого идентификатора набрано неправильно

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

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

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

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

Режим паники

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

Режим выписки

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

Ошибка производства

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

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

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

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

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

Parse Tree

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

Абстрактное синтаксическое дерево

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

Представление абстрактного синтаксического дерева

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