Методические указания (1114907), страница 8
Текст из файла (страница 8)
FIRST(F) ={‘,’, ε} FOLLOW(F) = {)}
-
Построим множество пунктов. Для этого пронумеруем правила и добавим фиктивное нулевое правило. После этого грамматика примет вид:
-
D’ -> D
-
D -> i(P);
-
P -> iF
-
P -> ε
-
F -> ,iF
-
F -> ε
А) Нулевой пункт I0 будет состоять из результата функции closure( { [D’ -> ∙D] } )
Б) Подсчитываем результат функции closure({[D’ -> ∙D]})
i) I0={ D’ -> ∙D}; Поскольку пункт стоит перед нетерминалом D, то пытаемся добавить в I0 пункт D -> ∙i(P); Такого пункта в I0 нет, поэтому добавляем его.
ii) I0 = { D’ -> ∙D, D -> ∙i(P);}. Поскольку пункт стоит только перед терминалами, а остальные нетерминалы уже проверялись, то множество пунктов I0 сформировано.
В) Подсчитываем I1 = goto(I0, D) = closure({[D’ -> D∙]})
i) I1 = {D’ -> D∙}. Поскольку пункт стоит только перед символами ε, то множество пунктов I1 сформировано.
Г) Подсчитываем I2 = goto(I0, i) = closure({[D -> i∙(P);]})
i) I2 = {D -> i∙(P);}. Поскольку пункт стоит только перед терминалами, то множество пунктов I2 сформировано.
Д) Подсчитываем I3 = goto(I2, ‘(‘) = closure ({[D -> i(∙P);]}).
i) I3 = {D -> i(∙P);}. Поскольку пункт стоит перед нетерминалом P, то пытаемся добавить в I3 пункты P -> ∙iF и P -> ∙ . Таких пунктов в I3 нет, поэтому добавляем их.
ii) I3 = {D -> i(∙P); , P -> ∙iF, P -> ∙}. Поскольку пункт стоит
только перед терминалами, а остальные нетерминалы уже
проверялись, то множество пунктов I3 сформировано.
Е) Подсчитываем I4 = goto(I3,P) = closure ({[D -> i(P∙);]}).
i) I4 = {D -> i(P∙);}. Поскольку пункт стоит только перед терминалами, то множество пунктов I4 сформировано.
Ж) Подсчитываем I5 = goto(I3, i) = closure({[P -> i∙F]}).
i) I5 = {P -> i∙F}. Поскольку пункт стоит перед нетерминалом F, то пытаемся добавить в I6 пункты F -> ∙,iF и F -> ∙ . Таких пунктов в I5 нет, поэтому добавляем их.
ii) I5 = {P -> i∙F, F -> ∙,iF, F -> ∙}. Поскольку пункт стоит
только перед терминалами, а остальные нетерминалы уже
проверялись, то множество пунктов I5 сформировано.
З) Подсчитываем I6 = goto(I4, ‘)’) = closure({[D -> i(P)∙;]}).
i) I6 = {D -> i(P)∙;}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I6 сформировано.
И) Подсчитываем I7 = goto(I5, F) = closure({[P -> iF∙]}).
i) I7 = {P -> iF∙}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I7 сформировано.
K) Подсчитываем I8 = goto(I5, ‘,’) = closure({[F ->,∙iF]}).
i) I8 = {F ->,∙iF}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I8 сформировано.
И) Подсчитываем I9 = goto(I6, ;) = closure({[D -> i(P);∙]}).
i) I9 = {D -> i(P);∙}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I9 сформировано.
Л) Подсчитываем I10 = goto(I8, i) = closure({[F ->,i∙F]}).
i) I10 = {F ->,i∙F}. Поскольку пункт стоит перед нетерминалом F, то пытаемся добавить в I10 пункты F -> ∙,iF и F -> ∙ . Таких пунктов в I10 нет, поэтому добавляем их.
ii) I10 = {F ->,i∙F, F -> ∙,iF, F -> ∙}. Поскольку пункт стоит
только перед терминалами, а остальные нетерминалы уже
проверялись, то множество пунктов I10 сформировано.
М) Подсчитываем I11 = goto(I10, F) = closure({[F ->,iF∙]}).
i) I11 = {F ->,iF∙}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I11 сформировано.
Л) Подсчитываем I12 = goto(I10, ‘,’) = closure({[F ->,∙iF]}).
i) I12 = {F ->,∙iF}. Поскольку пункт стоит только перед
терминалами, то множество пунктов I12 сформировано. Замечаем, что I12 = I8, поэтому не формируем нового множества пунктов. Таким образом, результат этого шага I8 = goto(I10, ‘,’) = {F ->,∙iF}.
Н) Больше множеств пунктов построить нельзя, поскольку либо все пункты расположены либо после символов ε, либо не порождают новых состояний.
Приведем подпрограммы для обработки ошибок.
Множество пунктов для данной грамматики имеет вид:
-
I0 = {D’ -> ∙D, D -> ∙i(P);}
-
I1 = {D’ -> D∙}
-
I2 = {D -> i∙(P);}
-
I3 = {D -> i(∙P); , P -> ∙iF, P -> ∙}
-
I4 = {D -> i(P∙);}
-
I5 = {P -> i∙F, F -> ∙,iF, F -> ∙}
-
I6 = {D -> i(P)∙;}
-
I7 = {P -> iF∙}
-
I8 = {F ->,∙iF}
-
I9 = {D -> i(P);∙}
-
I10 = {F ->,i∙F, F -> ∙,iF, F -> ∙}
-
I11 = {F ->,iF∙}
-
Диаграмма переходов представляет собой ориентированный граф, вершинами которого являются состояния, а дугами – переходы между этими состояниями.
Матрица смежности этого графа будет иметь вид.
Состояние | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
0 | - | D | i | - | - | - | - | - | - | - | - | - |
1 | - | - | - | - | - | - | - | - | - | - | - | - |
2 | - | - | - | ( | - | - | - | - | - | - | - | - |
3 | - | - | - | - | P | i | - | - | - | - | - | - |
4 | - | - | - | - | - | - | ) | - | - | - | - | - |
5 | - | - | - | - | - | - | - | F | , | - | - | - |
6 | - | - | - | - | - | - | - | - | - | ; | - | - |
7 | - | - | - | - | - | - | - | - | - | - | - | - |
8 | - | - | - | - | - | - | - | - | - | - | i | - |
9 | - | - | - | - | - | - | - | - | - | - | - | - |
10 | - | - | - | - | - | - | - | - | , | - | - | F |
11 | - | - | - | - | - | - | - | - | - | - | - | - |
Диаграмма переходов, построенная на основании приведенной выше матрицы смежности, имеет вид:
-
Строим таблицу SLR-анализатора.
Рассматриваем последовательно каждое состояние, заполняя функции action и goto в таблице.
А) Для множества пунктов I0 получаем action[I0, i] = s2 по правилу 2.1. алгоритма 4.2., goto[I0, D] = 1 по правилу 3 алгоритма 4.2..
Б) Для множества пунктов I1 получаем action[I1, $] = accept по правилу 5 алгоритма 4.2.
В) Для множества пунктов I2 получаем action[I2, (] = s3 по правилу 2.1. алгоритма 4.2.
Г) Для множества пунктов I3 получаем action[I3, )] = r3 по правилу 2.2. алгоритма 4.2., action[I3, i] = s5 по правилу 2.1. алгоритма 4.2., goto[I3, P] = 4 по правилу 3 алгоритма 4.2.
Д) Для множества пунктов I4 получаем action[I4, )] = s6 по правилу 2.1. алгоритма 4.2.
Е) Для множества пунктов I5 получаем action[I5, )] = r5 по правилу 2.2. алгоритма 4.2., action[I5, ‘,’] = s8 по правилу 2.1. алгоритма 4.2., goto[I5, F] = 7
Ж) Для множества пунктов I6 получаем action[I6, ;] = s9 по правилу 2.1. алгоритма 4.2..
З) Для множества пунктов I7 получаем action[I7, )] = r2 по правилу 2.2. алгоритма 4.2..
И) Для множества пунктов I8 получаем action[I8, i] = s10 по правилу 2.1. алгоритма 4.2.
К) Для множества пунктов I9 получаем action[I9, $] = r1 по правилу 2.2. алгоритма 4.2..
Л) Для множества пунктов I10 получаем action[I10, )] = r5 по правилу 2.2. алгоритма 4.2., action[I10, ‘,’] = s8 по правилу 2.1. алгоритма 4.2., goto[I10, F] = 11 по правилу 3 алгоритма 4.2.
М) Для множества пунктов I11 получаем action[I10, )] = r4 по правилу 2.2. алгоритма 4.2.