Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Все_пособие_редактир.doc
Скачиваний:
175
Добавлен:
31.10.2018
Размер:
2.51 Mб
Скачать

7.4.5 Обработка ошибок переноса/свертки

При обнаружении ошибок синтаксический анализатор приоритета операторов вызывает программу восстановления после ошибок. При обращении к матрице приоритетов для принятия решения о переносе или свертке можно обнаружить, что между символом на вершине стека и очередным входным символом отношения отсутствует. Предположим, что на вершине стека находятся а и b (b на вершине стека), во входном потоке — с и d (c — первый), а между b и с нет отношений приоритетов. Для восстановления после этой ошибки нужно изменить стек или входной буфер (а может быть, и тот и другой). Можно изменить символы, вставив их в стек или входной буфер или удалить оттуда. При вставке и изменении следует избегать бесконечного цикла, в котором постоянно вставляются cимволы в буфер, перенести или свернуть которые невозможно.

Один из способов гарантировать отсутствие зацикливания — это обеспечить возможность переноса символа после восстановления (если текущий символ — $, следует убедиться, что во входной поток не вставляются новые символы, а стек в конце концов прекращается). Например, при ab в стеке и cd во входной строке, если а≤ с, мы можем снять со стека b. Другой способ — удаление из входного потока с при b d . Третий способ заключается в поиске такого е, что b е ≤ с , и вставке е во входной поток с. В более общем виде, если единственный символ для вставки найти не удается, мы можем вставить строку символов, такую, что b е1 ег en с.

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

Пример 24

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

id

(

)

$

id

еЗ

еЗ

•>

•>

(

<•

<•

е4

)

еЗ

еЗ

•>

•>

$

<•

<•

е2

e1

Рис. 35. Матрица приоритета операторов с подпрограммами обработки ошибок

Сущность этих подпрограмм состоит в следующем.

el: /* Вызывается при отсутствии выражения в целом * / Вставляет id во входной поток

Диагностическое сообщение: отсутствует операнд

е2: /* Вызывается, когда выражение начинается с правой скобки */. Удалить ")" из входного потока

Диагностическое сообщение: несбалансированная правая скобка

еЗ: /* Вызывается, когда id или ) следует за id или ( */ Вставляет во входной поток +

Диагностическое сообщение: отсутствует оператор

е4: /* Вызывается при завершении выражения левой скобкой */ Снимает ( со стека

Диагностическое сообщение: отсутствует правая скобка

Рассмотрим работу этого механизма с неверной входной строкой id+). Первые дейст­вия, предпринимаемые синтаксическим анализатором — перенос id, свертка в Е и перенос +. После этих дейст­вий получаем следующую конфигурацию.

Стек Вход

$E+ )$

Поскольку + >), вызывается свертка для основы +. Подпрограмма проверки ошибок при свертке должна просмотреть наличие E слева и справа от оператора. Обнаружив, что один из них отсутствует, она выдает сообщение об ошибке "отсутствует операнд" и все равно выполняет свертку.

Теперь конфигурация принимает вид

Стек Вход

$E )$

Между $ и ) нет отношений приоритетов, и запись на рис. 35 для этой пары симво­лов — е2. Подпрограмма е2 выводит диагностическое сообщение "несбалансированная правая скобка" и удаляет правую скобку из входного потока. При этом достигается ко­нечная конфигурация синтаксического анализатора

Стек Вход

$E $

В качестве технологии синтаксического анализа общего назначения синтаксический анализ приоритета операторов имеет ряд недостатков. Например, с его помощью сложно обрабатывать лексемы вроде знака "минус", который имеет два разных приорите­та — в зависимости от того, является ли он унарным или бинарным. Кроме того, класс грамма­тик, с которыми может работать такой синтаксический анализатор, весьма невелик.

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