Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 7:

Восходящие анализаторы

Таблица LALR-анализатора для грамматики G1

Теперь можно построить таблицу LR-анализатора:

State action goto
a b $ S A
0 s3 s4 1 2
1 accept
2 s6 s7 5
3 s3 s4 8
4 r3 r3
5 r1
6 s6 s7 9
8 r2 r2
9 r2

Нетрудно заметить, что пары состояний 3 и 6, 4 и 7, 8 и 9 различаются только вторыми компонентами, определяющих их ситуаций. Поэтому мы можем "склеить" эти пары. В результате получится таблица LALR-анализатора:

State action goto
a b $ S A
0 s36 s47 1 2
1 accept
2 s36 s47 5
36 s36 s47 89
47 r3 r3 r3
5 r1
89 r2 r2 r2

Пример LR(1)-грамматики

Таким образом, LALR анализатор имеет значительное преимущество в размере таблиц по сравнению с LR. Однако, существуют грамматики, которые можно обработать LR анализатором, но нельзя LALR анализатором. LALR анализатор будет считать их неоднозначными, а LR анализатор не будет.

Пример.Грамматика

S -> aAd   
S -> bBd
S -> aBe
S -> bAe
A -> c
B -> c

не является LALR грамматикой, поскольку для входной цепочки ac мы можем выполнить свертку либо по правилу A -> c (если текущий входной символ d ) либо по правилу B -> c (если текущий входной символ e ).

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

Неоднозначные грамматики. Конфликты "перенос-свертка"

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

Рассмотрим сначала конфликты типа перенос-свертка ( shift/reduce ). Конфликты данного типа возникают, когда в процессе работы анализатора возникает выбор между переносом текущего символа на вершину стека и сверткой последовательности, расположенной на вершине стека.

Пример.Пусть дана грамматика G1, имеющая следующий набор правил:

(1) stmt -> if expr then stmt
(2) stmt -> if expr then stmt else stmt
(3) stmt -> other
(1) stmt -> if expr then stmt
(2) stmt -> if expr then stmt else stmt
(3) stmt -> other

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

На следующем слайде рассмотрим, что происходит при анализе следующей входной цепочки:

if E1 then if E2 then S1 else S2.