3.2. Построение множества символов-предшественников
Пусть G = (N, Σ, P, S)– КС-грамматика. Для произвольной цепочкиαопределимS(α) как множество терминалов, с которых начинаются строки, выводимыеизα. Еслиα * e, тоeтакже принадлежитS(α).
Алгоритм:
Пусть α = X1 X2 … Xn.
1) Положить S(α) =
2) i = 1
3) Вычисляем S(Xi)
3.1) Если Xi Σ {e}, тоS(Xi) = {Xi}
3.2) Иначе {Xj βj} P, j = 1, 2, …, m,

3.3) S(α) = S(α) (S(Xi) – {e})
3.4) Если e S(Xi)
3.4.1) Если i < n, тоi = i + 1, переход на шаг 3
3.4.2) Иначе S(α) = S(α) {e}, переход на шаг 4
3.5) Иначе переход на шаг 4
4) Конец алгоритма
Чтобы вычислить S(α)для всехнетерминаловграмматики, необходимо, пока удается добавлять новые элементы в какое-либо множествоS(A), A N, повторять алгоритм для каждогоA N. Это позводит в будущем более просто находить множество символов-предшественников для любой цепочки, т.к. упростится выполнение шага 3.
Пример:
S(E) = S(T) = {(, id}
S(E1´) = {+}
S(E2´) = {e}
S(T1´) = {*}
S(T2´) = {e}
S(F1) = {(}
S(F2) = {id}
3.3. Построение множества символов-последователей
Пусть G = (N, Σ, P, S)– КС-грамматика. ДлянетерминалаA NопределимF(A)как множество терминалов, с которых начинаются строки, выводимые в грамматике послеA.
Алгоритм:
Пусть X N.
1) Положить F(X) =
2) Положить F(S) = {$}
3) Пока удается добавлять новые элементы в какое-либо множество F(X), повторять
3.1) Пусть {A αBβ} P, B N, α, β (N Σ)*иβ ≠ e, тогдаF(B) = F(B) (S(β) – {e})
3.2) Если β = eилиe S(β)(т.е.β * e), тоF(B) = F(B) F(A)
Пример:
F(E) = F(E´) = {), $}
F(T) = F(T´) = {+, ), $}
F(F) = {+, *, ), $}
3.4. Построение таблицы разбора
Имея множества символов-предшественников и множества символов-последователей, легко построить множества направляющих символов T(X):
T(X) = (S(X) – {e}) {F(X) | e S(X)}.
Пример:
T(E) = T(T) = {(, id}
T(E1´) = {+}
T(E2´) = {), $}
T(T1´) = {*}
T(T2´) = {+, ), $}
T(F1) = {(}
T(F2) = {id}
Также легко проверить, является ли грамматика грамматикой типа LL(1): если имеются альтернативы Ai αi, i = 1, 2, …, n, то грамматика будет относиться к типу LL(1), если
T(Ai) T(Aj) = , i ≠ j.
Пример:
T(E1´) T(E2´) =
T(T1´) T(T2´) =
Построение таблицы разбора:
1) Помечаем грамматику
Пусть Pi– правило с номеромiиз множестваP,i = 1, 2, …, n. Тогда:
1) Полагаем i = 1, count = 0
2) Пусть Pi+k–1 = Ak αk, k = 1, 2, …, p, тогда
2.1) I(Ak) = count + k, count = count + p
2.2) Для каждой цепочки αk = X1, X2, …, Xm, гдеm = |αk|, полагаем
2.2.1) I(Xj) = count + j, j = 1, 2, …, m
2.2.2) count = count + m
3) i = i + 1
4) Если i < n, переход на шаг 2, иначе – конец алгоритма
Для рассмотренного выше примера
(1) E (1) T (2) E´ (3)
(2) E´ (4) + (6) T (7) E´ (8)
(3) E´ (5) e (9)
(4) T (10) F (11) T´ (12)
(5) T´ (13) * (15) F (16) T´ (17)
(6) T´ (14) e (18)
(7) F (19) ( (21) E (22) ) (23)
(8) F (20) id (24)
2)Строим множестваT(X)
3) Заполняем таблицу
Введем множество индексов элементов правил, стоящих по левую сторону от знака вывода (L). В нашем случаеL = {1, 4, 5, 10, 13, 14, 19, 20}. Введем также множество индексов элементов правил, являющихся самыми правыми в своем правиле (R). В нашем случаеR = {3, 8, 9, 12, 17, 18, 23, 24}.
Тогда






|
ID |
X |
Terminals |
Jump |
Accept |
Stack |
Return |
Error |
|
1 |
E |
(, id |
2 |
|
|
|
|
|
2 |
T |
(, id |
10 |
|
true |
|
|
|
3 |
E´ |
+, ), $ |
4 |
|
|
|
|
|
4 |
E´ |
+ |
6 |
|
|
|
false |
|
5 |
E´ |
), $ |
9 |
|
|
|
|
|
6 |
+ |
+ |
7 |
true |
|
|
|
|
7 |
T |
(, id |
10 |
|
true |
|
|
|
8 |
E´ |
+, ), $ |
4 |
|
|
|
|
|
9 |
e |
), $ |
0 |
|
|
true |
|
|
10 |
T |
(, id |
11 |
|
|
|
|
|
11 |
F |
(, id |
19 |
|
true |
|
|
|
12 |
T´ |
+, *, ), $ |
13 |
|
|
|
|
|
13 |
T´ |
* |
15 |
|
|
|
false |
|
14 |
T´ |
+, ), $ |
18 |
|
|
|
|
|
15 |
* |
* |
16 |
true |
|
|
|
|
16 |
F |
(, id |
19 |
|
true |
|
|
|
17 |
T´ |
+, *, ), $ |
13 |
|
|
|
|
|
18 |
e |
+, ), $ |
0 |
|
|
true |
|
|
19 |
F |
( |
21 |
|
|
|
false |
|
20 |
F |
id |
24 |
|
|
|
|
|
21 |
( |
( |
22 |
true |
|
|
|
|
22 |
E |
(, id |
1 |
|
true |
|
|
|
23 |
) |
) |
0 |
true |
|
true |
|
|
24 |
id |
id |
0 |
true |
|
true |
|
