Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория языков программирования и методы трансляции..pdf
Скачиваний:
28
Добавлен:
05.02.2023
Размер:
3.41 Mб
Скачать

167

 

 

S0

 

real

 

VARS

S2

 

S1

ID

IDLIST

 

a-z

 

 

S4

S3

 

S5

 

 

a-z

,

;

 

 

S7

 

S6

ID

 

 

S8

Рисунок 5.1 – Граф переходов между состояниями анализатора

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

5.3.2 ПОСТРОЕНИЕ ТАБЛИЦЫ

Алгоритм построения LR-таблицы разбора следующий:

1.Создаем таблицу из #X+1 столбца (по столбцу на каждый терминал a Σ и нетерминал A N, а также столбец для маркера конца цепочки

« ») и #I строк (по одной на каждое состояние анализатора).

2.В каждую ячейку таблицы записываем элемент ERROR.

3.Для всех состояний Si I выполняем следующие действия:

3.1.Если:

а) в состоянии Si присутствует LR-ситуация с точкой не в кон-

це правила, т.е. [A α • Xβ | a]Si, A N′, X X, α X*, β X*, a Σ{ } и

168

б) в графе переходов есть переход из состояния Si в некоторое состояние Sj, помеченный меткой X, т.е. (Si, Sj) R, g((Si, Sj)) = X,

то T(Si, X) = Sj.

3.2.Если в состоянии Si присутствует LR-ситуация с точкой в конце правила, т.е. [A α • | a]Si, A N′, α X+, a Σ{ }, то:

а) если (A α) P′ – это искусственное стартовое правило, т.е. A

= S′ (в этом случае a = ), то T(Si, a) = HALT,

б) иначе T(Si, a) = Rk, где k – номер правила (A α) P в грамматике, т.е. Pk = (A α).

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Если применить данный алгоритм к грамматике

(0)VARSVARS

(1)VARS real IDLIST ;

(2)IDLIST IDLIST , ID

(3)IDLIST ID

(4)ID a-z

то получим табл. 5.2.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

5.3.3 LR-КОНФЛИКТЫ

Если таблица для грамматики типа LL заполняется построчно, то в описанном выше алгоритме элементы заносятся в грамматику точечно. Мо-

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

Такая ситуация называется LR-конфликтом. В общем случае конфликты могут быть четырех типов:

169

1.При попытке записать в ячейку сдвиг Si, обнаруживаем, что там уже содержится свертка Rj (конфликт типа сдвиг-свертка);

2.При попытке записать в ячейку свертку Ri, обнаруживаем, что там уже содержится сдвиг Sj (конфликт типа свертка-сдвиг);

3.При попытке записать в ячейку сдвиг Si, обнаруживаем, что там уже содержится другой сдвиг Sj (конфликт типа сдвиг-сдвиг);

4.При попытке записать в ячейку свертку Ri обнаруживаем, что там уже содержится другая свертка Rj (конфликт типа свертка-свертка).

Последние два случая на практике встречаются редко, а первые два встречаются весьма часто. Например, возникновение конфликтов типа сдвиг-

сдвиг или свертка-свертка возможно при наличии в грамматике двух и более одинаковых правил.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Другой пример (проверьте самостоятельно):

S A S

S S A

S A S A

S → a

A → a

A A A

·· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Вподобных случаях делается вывод о том, что грамматика некорректна

идальнейшее построение таблицы разбора прекращается. При возникнове-

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

рует последний пример в разделе 5.1). Поэтому при возникновении конфлик-

170

та типа сдвиг-свертка пишем в ячейку таблицы сдвиг Si вместо свертки Rj.

Если же возникает конфликт свертка-сдвиг, то оставляем в ячейке сдвиг Sj, а

свертку Ri игнорируем. Хотя есть специфические грамматики, где свертка является более предпочтительной, они редко встречаются на практике.

5.3.4 РАЗБОР ЦЕПОЧКИ ПО ТАБЛИЦЕ

Для разбора, как уже было сказано, требуется один или два стека

(магазина). В начале в стек состояний помещается состояние S0 (или просто его индекс – 0). То есть конфигурацией LR-автомата будет

(S0, a1a2an).

Далее конфигурация меняется по описанным ранее правилам до тех пор, пока не будет достигнута ячейка таблицы с элементом HALT или

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

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

В табл. 5.3 рассмотрим, как с помощью табл. 5.2 разбирается строка

«real a, b, c;». В данном примере при разборе используются два стека.

Таблица 5.3 – Пример разбора строки

Позиция

Стек

Стек

символов

состояний

 

real a, b, c;

 

 

0

 

 

 

 

 

 

 

 

 

Входной символ – real, T(S0, real) = S2, сдвиг в состояние 2:

 

 

real a, b, c;

 

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – a, T(S2, a-z) = S5, сдвиг в состояние 5:

 

 

real a , b, c;

 

 

 

a

 

5

 

 

real

 

2

 

 

 

 

 

 

171

0

Входной символ – «,», T(S5, «,») = R4, приведение по правилу 4 (ID a-z). В

его левой части один элемент, снимаем со стеков по одному элементу:

real a , b, c;

real

 

2

 

 

 

 

0

 

 

 

 

 

 

На вершине стека остается состояние S2. Следовательно, новым состоянием

будет T(S2, ID) = S4:

 

 

 

 

real a , b, c;

 

 

 

ID

 

4

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «,», T(S4, «,») = R3, приведение по правилу 3 (IDLIST

ID). Снимаем со стеков по одному элементу:

 

 

real a , b, c;

 

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Новым состоянием будет T(S2, IDLIST) = S3:

 

 

real a , b, c;

 

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «,», T(S3, «,») = S7, сдвиг в состояние 7:

 

 

real a, b, c;

 

 

 

 

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – b, T(S7, a-z) = S5, сдвиг в состояние 5:

 

 

real a, b , c;

 

 

 

b

 

5

 

 

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

 

 

172

0

Входной символ – «,», T(S5, «,») = R4, приведение по правилу 4 (ID a-z).

Снимаем со стеков по одному элементу:

real a, b , c;

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Новым состоянием будет T(S7, ID) = S8:

 

 

real a, b , c;

 

 

 

ID

 

8

 

 

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «,», T(S8, «,») = R2, приведение по правилу 2 (IDLIST

IDLIST , ID). Снимаем со стеков по три элемента:

 

 

real a, b , c;

 

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Новым состоянием будет T(S2, IDLIST) = S3:

 

 

real a, b , c;

 

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «,», T(S3, «,») = S7, сдвиг в состояние 7:

 

 

real a, b, c;

 

 

 

 

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ с T(S7, a-z) = S5, сдвиг в состояние 5:

 

 

real a, b, c ;

 

 

 

c

 

5

 

 

 

 

 

 

173

 

 

 

 

,

 

7

 

 

 

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «;», T(S5, «;») = R4, приведение по правилу 4 (ID a-z).

Снимаем со стеков по одному элементу:

real a, b, c ;

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Новым состоянием будет T(S7, ID) = S8:

 

 

real a, b, c ;

 

 

 

ID

 

8

 

 

,

 

7

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «;», T(S5, «;») = R2, приведение по правилу 2 (IDLIST

IDLIST , ID). Снимаем со стеков по три элемента:

 

 

real a, b, c ;

 

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Новым состоянием будет T(S2, IDLIST) = S3:

 

 

real a, b, c ;

 

 

 

IDLIST

 

3

 

 

real

 

2

 

 

 

 

0

 

 

 

 

 

 

Входной символ – «;», T(S3, «;») = S6, сдвиг в состояние 6:

 

 

real a, b, c;

 

 

 

 

;

 

6

 

 

IDLIST

 

3

 

 

real

 

2