Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error()

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

Если в момент обнаружения ошибки на верхушке магазина оказался нетерминальный символ A и для него нет правила, соответствующего входному символу, то сканируем вход до тех пор, пока не встретим символ либо из FIRST(A), либо из FOLLOW(A). В первом случае разворачиваем A по соответствующему правилу, во втором - удаляем A из магазина.

Если на верхушке магазина терминальный символ, то можно удалить все терминальные символы с верхушки магазина вплоть до первого (сверху) нетерминального символа и продолжать так, как это было описано выше.

Разбор снизу-вверх типа сдвиг-свертка

Основа

В процессе разбора снизу-вверх типа сдвиг-свертка строится дерево разбора входной цепочки, начиная с листьев (снизу) к корню (вверх). Этот процесс можно рассматривать как «свертку» цепочки w к начальному символу грамматики. На каждом шаге свертки подцепочка, которую можно сопоставить правой части некоторого правила вывода, заменяется символом левой части этого правила вывода, и если на каждом шаге выбирается правильная подцепочка, то в обратном порядке прослеживается правосторонний вывод (рис. 4.7). Здесь ко входной цепочке, так же как и при анализе LL(1)-грамматик, приписан концевой маркер $.

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru
Рис. 4.7:  

Подцепочка сентенциальной формы, которая может быть сопоставлена правой части некоторого правила вывода, свертка по которому к левой части правила соответствует одному шагу в обращении правостороннего вывода, называется основой цепочки. Самая левая подцепочка, которая сопоставляется правой части некоторого правила вывода A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru , не обязательно является основой, поскольку свертка по правилу A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru может дать цепочку, которая не может быть сведена к аксиоме.

Формально, основа правой сентенциальной формы z - это правило вывода A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru и позиция в z, в которой может быть найдена цепочка Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru такие, что в результате замены Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru на A получается предыдущая сентенциальная форма в правостороннем выводе z. Таким образом, если S Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r* Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru , то A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru в позиции, следующей за Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru , это основа цепочки Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru . Подцепочка Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru справа от основы содержит только терминальные символы.

Вообще говоря, грамматика может быть неоднозначной, поэтому не единственным может быть правосторонний вывод Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru и не единственной может быть основа. Если грамматика однозначна, то каждая правая сентенциальная форма грамматики имеет в точности одну основу. Замена основы в сентенциальной форме на нетерминал левой части называется отсечением основы. Обращение правостороннего вывода может быть получено с помощью повторного применения отсечения основы, начиная с исходной цепочки w. Если w - слово в рассматриваемой грамматике, то w = Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n, где Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n - n-я правая сентенциальная форма еще неизвестного правого вывода S = Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru 0 Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru 1 Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r... Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n-1 Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru r Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n = w.

Чтобы восстановить этот вывод в обратном порядке, выделяем основу Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n в Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n и заменяем Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n на левую часть некоторого правила вывода An Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n, получая (n - 1)-ю правую сентенциальную форму Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n-1. Затем повторяем этот процесс, т.е. выделяем основу Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n-1 в Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n-1 и сворачиваем эту основу, получая правую сентенциальную форму Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru n-2. Если, повторяя этот процесс, мы получаем правую сентенциальную форму, состоящую только из начального символа S, то останавливаемся и сообщаем об успешном завершении разбора. Обращение последовательности правил, использованных в свертках, есть правый вывод входной строки.

Таким образом, главная задача анализатора типа сдвиг-свертка - это выделение и отсечение основы.

LR(1)-анализаторы

В названии LR(1) символ L указывает на то, что входная цепочка читается слева-направо, R - на то, что строится правый вывод, наконец, 1 указывает на то, что анализатор видит один символ непрочитанной части входной цепочки.

LR(1)-анализ привлекателен по нескольким причинам:

  • LR(1)-анализ - наиболее мощный метод анализа без возвратов типа сдвиг-свертка;
  • LR(1)-анализ может быть реализован довольно эффективно;
  • LR(1)-анализаторы могут быть построены для практически всех конструкций языков программирования;
  • класс грамматик, которые могут быть проанализированы LR(1)-методом, строго включает класс грамматик, которые могут быть проанализированы предсказывающими анализаторами (сверху-вниз типа LL(1)).

Схематически структура LR(1)-анализатора изображена на рис. 4.8. Анализатор состоит из входной ленты, выходной ленты, магазина, управляющей программы и таблицы анализа (LR(1)-таблицы), которая имеет две части - функцию действий (Action) и функцию переходов (Goto). Управляющая программа одна и та же для всех LR(1)-анализаторов, разные анализаторы отличаются только таблицами анализа.

Программа анализатора читает символы на входной ленте по одному за шаг. В процессе анализа используется магазин, в котором хранятся строки вида S0X1S1X2S2...XmSm (Sm - верхушка магазина). Каждый Xi - символ грамматики (терминальный или нетерминальный), а Si - символ состояния.

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

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru
Рис. 4.8:  

Элемент функции действий Action[Sm, ai] для символа состояния Sm и входа ai Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru T Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru {$}, может иметь одно из четырех значений:

  • shift S (сдвиг), где S - символ состояния,
  • reduce A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru (свертка по правилу грамматики A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru ),
  • accept (допуск),
  • error (ошибка).

Элемент функции переходов Goto[Sm, A] для символа состояния Sm и входа A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru N, может иметь одно из двух значений:

  • S, где S - символ состояния,
  • error (ошибка).

Конфигурацией LR(1)-анализатора называется пара, первая компонента которой - содержимое магазина, а вторая - непросмотренный вход:

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru

Эта конфигурация соответствует правой сентенциальной форме

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru

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

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

Очередной шаг анализатора определяется текущим входным символом ai и символом состояния на верхушке магазина Sm следующим образом.

Пусть LR(1)-анализатор находится в конфигурации

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru

Анализатор может проделать один из следующих шагов:

  • Если Action[Sm, ai] = shift S, то анализатор выполняет сдвиг, переходя в конфигурацию

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru

Таким образом, в магазин помещаются входной символ ai и символ состояния S, определяемый Action[Sm, ai]. Текущим входным символом становится ai+1.

  • Если Action[Sm, ai] = reduce A Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru , то анализатор выполняет свертку, переходя в конфигурацию

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru

где S = Goto[Sm-r, A] и r - длина Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru , правой части правила вывода.

Анализатор сначала удаляет из магазина 2r символов (r символов состояния и r символов грамматики), так что на верхушке оказывается состояние Sm-r. Затем анализатор помещает в магазин A - левую часть правила вывода, и S - символ состояния, определяемый Goto[Sm-r, A]. На шаге свертки текущий входной символ не меняется. Для LR(1)-анализаторов Xm-r+1...Xm - последовательность символов грамматики, удаляемых из магазина, всегда соответствует Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru - правой части правила вывода, по которому делается свертка.

После осуществления шага свертки генерируется выход LR(1)-анализатора, т.е. исполняются семантические действия, связанные с правилом, по которому делается свертка, например, печатаются номера правил, по которым делается свертка.

Заметим, что функция Goto таблицы анализа, построенная по грамматике G, фактически представляет собой функцию переходов детерминированного конечного автомата, распознающего активные префиксы G.

  • Если Action[Sm, ai] = accept, то разбор успешно завершен.
  • Если Action[Sm, ai] = error, то анализатор обнаружил ошибку, и выполняются действия по диагностике и восстановлению.

Пример 4.8. Рассмотрим грамматику арифметических выражений G = ({E, T, F}, {id, +, *}, P, E) с правилами:

  (1) E Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru E + T
  (2) E Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru T
  (3) T Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru T * F
  (4) T Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru F
  (5) F Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru id
   

На рис. 4.9 изображены функции Action и Goto, образующие LR(1)-таблицу для этой грамматики. Для Элемент Si функции Action означает сдвиг и помещение в магазин состояния с номером i, Rj - свертку по правилу номер j, acc - допуск, пустая клетка - ошибку. Для функции Goto символ i означает помещение в магазин состояния с номером i, пустая клетка - ошибку.

На входе id + id * id последовательность состояний магазина и входной ленты показаны на рис. 4.10. Например, в первой строке LR-анализатор находится в нулевом состоянии и «видит» первый входной символ id. Действие S6 в нулевой строке и столбце id в поле Action (рис. 4.9) означает сдвиг и помещение символа состояния 6 на верхушку магазина. Это и изображено во второй строке: первый символ id и символ состояния 6 помещаются в магазин, а id удаляется со входной ленты.

Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru
Рис. 4.9:  
Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru
Рис. 4.10:  

Текущим входным символом становится +, и действием в состоянии 6 на вход + является свертка по F Восстановление после синтаксических ошибок. В приведенных программах рекурсивного спуска использовалась процедура реакции на синтаксические ошибки error() - student2.ru id. Из магазина удаляются два символа (один символ состояния и один символ грамматики). Затем анализируется нулевое состояние. Поскольку Goto в нулевом состоянии по символу F - это 3, F и 3 помещаются в магазин. Теперь имеем конфигурацию, соответствующую третьей строке. Остальные шаги определяются аналогично.

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