Преобразование КС- грамматик Лекция 8

advertisement
Лекция 8
Преобразование КСграмматик
• Любая грамматика является генератором языка. Одновременно
грамматика придает цепочкам языка полезную структуру. Любую
грамматику часто требуется модернизировать так, чтобы
порождаемый ею язык приобрел нужную структуру.
• Пример 8.1. G: EE+E | E*E | (E) | a
• Данная грамматика неоднозначна из-за правил вида
ЕЕ+Е| Е*Е. Эту неоднозначность можно
устранить, взяв вместо G грамматику G1 cо
схемой:
•
EE+T| E*T| T
•
T(E) | a
• Другой недостаток G, которым обладает также и
G1, заключается в том, что никак не отражен тот
факт, что приоритет операции + ниже, чем
приоритет операции *.
• a+a*a
подразумевает
(a+a)*a
• a*a+a
(a*a)+a
соответственно
• Последний недостаток устраняется грамматикой
G2 со схемой:
• E  E+T
• T  T *F| F
• F (E) | a
• Не существует общего метода
преобразования грамматики, который
придавал бы языку требуемую структуру.
Рассмотрим ряд преобразований, которые не
портят языка, порождаемого грамматикой.
Определение 8.1
• Назовем нетерминальный символ ХN бесполезным
в КС – грамматике G = (N, , P, S), если в ней нет
вывода вида S *Xy*xy, где ,x, y принадлежат
*.
• Другими словами: некоторый нетерминальный
символ грамматики является бесполезным, если не
существует ни одной терминальной цепочки,
порождаемой этим символом. Если бесполезный
символ появился в одном из выводов грамматики, то
такой вывод никогда не может быть достроен до
полного вывода. Если бесполезным символом
является начальный символ грамматики, то язык,
порождаемый такой грамматикой, пуст.
• Решать проблему пустоты множества {| A*,
*} помогает следующий алгоритм.
Алгоритм 8.1
•
•
•
•
•
•
•
•
•
•
Не пуст ли язык L(G)?
Вход.
КС – грамматика G = (N, , P, S)
Выход.
«Да», если L(G) ,
«Нет» в противном случае.
Метод. Строим рекурсивно множества N0, N1, … следующим
образом:
Положим N0 =  и i=1
Положим Ni = Ni-1  {A | A    P &  (Ni-1)* }
Если Ni  Ni-1, положим i=i+1 и перейдем к шагу (2). В
противном случае положим Nl = Ni.
Если S  Nl, выдать «Да», в противном случае - «Нет».
Так как Nl  N, то алгоритм должен остановиться после n+1
повторений шага 2, если множество N содержит n
нетерминалов.
Теорема 8.1
• Алгоритм 7.1. говорит «Да» тогда и только тогда,
когда существует вывод S *  для некоторой
цепочки   *.
• Для доказательства леммы необходимо доказать
утверждения:
• (1) если A Ni, то A * w для некоторой цепочки w
*
• (2) если A * w для некоторой цепочки w *, то A
Nl.
• Докажем сначала индукцией по i, что выполнено (1).
• Базис индукции при i =0 не нуждается в
доказательстве, так как в этом случае N0 = ; при i=1
N1 =   {A A   P,   *}, т.е. (1) справедливо.
• Предположим, что для некоторого i утверждение (1)
выполнено. Докажем, что оно выполнено также и для
i+1. Возьмем A Ni+1. Если также A  Ni, то шаг
индукции тривиален. Если A Ni+1\ Ni, то существует
правило A  X1X2…Xk, где каждый Xj принадлежит
либо , либо Ni. Следовательно, для каждого Xj
можно найти такую цепочку wj, что Xj * wj: если
Xj, то wj = Xj, в противном случае существование
цепочки wj следует из того, что условие (1)
выполнено для i. Тогда AX1X2…Xk*w1X2…Xk *
w1w2…Xk *w1w2… wk, где w1w2… wk*. Если k =
0, то все предыдущие рассуждения также верны (в
этом случае правило имеет вид A  ). Утверждение
(1) доказано.
• Теперь докажем, что утверждение (2) также
выполнено. Определение множеств Ni
гарантирует, что если Ni = Ni-1, то Ni = Ni+1 =
... В силу сделанного замечания необходимо
доказать, что выполнено следующее
утверждение: (3) если A * w, то A  Ni для
некоторого i или если A n w, то A  Ni для
некоторого i и произвольного n. Докажем
последнее индукцией по n.
• Базис индукции. Если n = 1, то утверждение
(3) выполнено при i =1, так как в этом случае
A 1 w, причем w *, т.е. существует
правило A w, вследствие чего A N1.
• Допустим, что (3) выполнено для некоторого
n и имеет место A n+1 w. Тогда можно
написать A X1X2…Xk n w, где цепочка w
такова, что Xj nj wj для каждого j и nj  n.
Здесь wj есть крона поддерева вывода с
корнем Xj. Согласно (3), если Xj  N, то Xj 
Nij для некоторого ij. Если Xj , то k =0.
Пусть i = 1+ max(i1, i2,..., ik). Тогда по
определению A  Ni. Индукция завершена.
Если в утверждениях (1) и (2) положить A= S,
то получим утверждение теоремы.
Следствие
• Для КС – грамматики G проблема пустоты
языка L(G) разрешима.
Определение 8.2
• Символ Х  N   назовем недостижимым в
КС–грамматике G = (N, , P, S), если Х не
появляется ни в одной цепочке, выводимой в
G (не существует вывода S * X).
Алгоритм 8.2
•
•
•
•
•
•
•
•
•
•
Устранение недостижимых символов.
Вход.
КС – грамматика G=(N, , P, S)
Выход.
КС – грамматика G’=(N’, ’, P’, S), в которой
(1) L(G’) = L(G)
(2) для всех Х  N’  ’ существуют такие цепочки  и
 из (N’’)*, что S *х.
Метод.
(1)Положим V0 = {S} и i=1
(2)Положим Vi = Vi-1  {x | Ах  P & АVi-1}
(3)Если Vi  Vi-1 положим i=i+1 и перейдем к шагу (2).
В противном случае положим ’= Vi  , N’ = Vi  N,
P’ построим как подмножество правил из P, таких,
которые содержат только символы из Vi, грамматика
G’ = (N’, ’, P’, S).
• Алгоритмы 8.1 и 8.2 похожи. Шаг (2)
алгоритма 8.2 можно повторить только
конечное число раз, т.к. Vi  N  . Кроме
того, доказательство индукцией по i
показывает, что S*G' X тогда и только
тогда, когда XVi для некоторого i.
Алгоритм 8.3
• Устранение бесполезных символов.
• Вход:
КС-грамматика G = (N, , P, S), у которой
L(G).
• Выход:
КС-грамматика G’ = (N’, ’, P’, S), у которой
• L(G’) = L(G) и в N’  ’ нет бесполезных символов.
• Метод:
• 1) применив к G алгоритм 8.1, получить Nl;
• положим G1 = (Nl, , P1, S), где P1 состоит из правил
множества P, содержащих только символы из Nl  .
• 2) применив к G1 алгоритм 8.2, получить G’=(N’, ’,
P’, S).
• Пример 8.2: G=({S, A, B}, {a, b}, P, S), где P состоит
из правил:
• Sa | A
• AAB
• Bb
• Применим к G алгоритм 8.3. На шаге (1) получим Nk
= {S, B} и G1=({S, B}, {a, b}, {Sa, Bb}, S). Применив
алгоритм 7.2, получим V2=V1={S, a}. Итак, G’=({S},
{a}, { Sa }, S).
• Если применить к G сначала алгоритм 8.2, то
окажется, что все символы достижимы, так что
грамматика не изменится. Затем применение
алгоритма 8.1 дает Nk = {S, B}, и результатом будет
грамматика G1, отличная от G.
Определение 8.3
• Назовем грамматику G = ( N, , P, S) грамматикой без
-правил, если либо P не содержит -правил, либо
есть точно одно правило S   и S не встречается в
правых частях остальных правил из P.
Алгоритм 8.4
• Преобразование в грамматику без -правил.
• Вход:
КС-грамматика G = ( N, , P, S).
• Выход:
эквивалентная КС-грамматика G=( N, ,
P, S) без
• -правил.
• Метод.
• 1). Построим N = A AN и A+G   и N"
=BBN &  B+G w  w  + посредством
применения алгоритма, аналогичного
алгоритму 8.1.
• 2). Положим P = .
• 3). Выделим в грамматике G правила вида
• A  0B11B22…k-1Bkk  P, k0, такие
что Bi  N при всех i, 1ik, j  ((N \
N))+ при всех j, 1 j  k, (т.е. ни один
символ цепочки j не принадлежит множеству
N).
• Пусть число таких правил будет М. Для каждого mого (1mМ) выделенного правила сформируем
множество Pm, куда поместим все правила вида
A0X11X22…k-1Xkk, где 0X11X22…k1Xkk  , а Xi есть либо Bi, либо , причем Xi может
быть равно Bi в некотором сформированном
правиле, если Bi  N"; если Bi  N", то во всех
построенных правилах Xi = . Если оказалось, что
все Bi  N", то в Pm будет помещено единственное
правило A012…k-1k при условии
012…k-1k  . В противном случае Pm = .
• Для всех Pm  выполнить P = P  Pm.
• 4). Добавить в P все правила B   (если их
там еще нет) для всех B  N, такие что  
((N \ N))+, т.е.    и не содержит
символов из множества N (все правила,
правые части которых содержат символы из
N, уже рассмотрены на шаге 3).
• 5). Если S  N, включить в P правила
SS, где S - новый нетерминальный
символ и положить N= N"  {S}. В противном
случае положить N= N" и S = S.
• 6) Положим G = ( N, , P, S').
•
•
•
•
•
•
•
•
Пример 8.3. Рассмотрим грамматику с правилами
(1) S  aSbS
(2) S  bSaS
(3) S  
Применим к ней алгоритм 8.4.
1) Множество N = N" = {S}.
2) Правила (1) и (2) содержат символ из N.
Применим к ним шаг 3 алгоритма. Для правила (1)
построим множество P1={SaSbS, SaSb, SabS,
Sab}. Для правила (2) построим множество
P2={SbSaS, SbSa, SbaS, Sba}. Множество P
= P1 P2.
•
•
•
•
•
•
•
•
•
•
•
Так как S  N, то добавим правило S’S | 
Результирующая грамматика имеет вид G' =(N",
, P', S'), где схему P' образуют правила
SaSbS, SaSb, SabS, Sab, SbSaS, SbSa,
SbaS, Sba, S’S, S
Пример 8.4. Рассмотрим грамматику с правилами
(1) A  
(2) B  
(3) M AB
(4) N  Ab
(5) K  ab
(6) S  KNM
Построим множества N = {A, B, M} и N" ={N, K,
S}.
• Правила (3), (4) и (6) содержат символы из N. Так
как ни A, ни B не принадлежат N", то для правила
(3) множество P1 будет пустым. Для правила (4)
множество P2 = { N  b} (A не принадлежит N"). Для
правила (6) множество P3 = { S  KN } (M не
принадлежит N"). Правило (5) будет добавлено в
результате выполнения шага 3 алгоритма.
• Результирующая грамматика имеет вид G' =(N", ,
P', S), где схему P' образуют правила
• (1) N  b
• (2) K  ab
• (3) S  KN
• Пример 8.5. Рассмотрим грамматику с
правилами
• (1) A  
• (2) A  c
• (3) B  
• (4) B  p
• (5) M AB
• (6) N  Ab
• (7) K  ab
• (8) S  KNM
• Построим множества N = {A, B, M} и N"
={N, K, S, A, B, M}.
• Правила (5), (6) и (8) содержат символы из
N. Так как A и B принадлежат N", то для
правила (5) множество P1 = { M AB, M B,
M A}. Для правила (6) множество P2 = {N
 b, N  Ab} (A принадлежит N"). Для
правила (8) множество P3 = {S  KN, S
KNM} (M принадлежит N"). Правила (2), (4),
(7) будут добавлены в результате
выполнения шага 3 алгоритма.
• Результирующая грамматика имеет вид G' =(N", ,
P', S), где схему P' образуют правила
• (1) A  c
• (2) B  p
• (3) M AB
• (4) M A
• (5) M B
• (6) N  Ab
• (7) N  b
• (8) K  ab
• (9) S  KNM
• (10) S  KN
•
•
•
•
•
•
•
•
•
Пример 8.6. Рассмотрим грамматику с правилами
(1) A  
(2) B  
(3) M AB
(4) M a
(5) N  Ab
(6) K  ab
(7) S  KNM
Построим множества N = {A, B, M} и N" ={N, K, S,
M}.
• Правила (3), (5) и (7) содержат символы из N. Так
как ни A, ни B не принадлежат N", то для правила
(3) множество P1 будет пустым. Для правила (5)
множество P2 = { N  b } (A не принадлежит N").
Для правила (7) множество P3 = { S  KN, S  KNM
} (M принадлежит N"). Правила (4) и (6) будут
добавлены в результате выполнения шага 3
алгоритма.
• Результирующая грамматика имеет вид G' =(N", ,
P', S), где схему P' образуют правила
• (1) M a
• (2) N  b
• (3) K  ab
• (4) S  KNM
• (5) S  KN
•
•
•
•
•
•
•
•
Пример 8.7. Рассмотрим грамматику с правилами
(1) A  
(2) A  c
(3) B  
(4) M AB
(5) S  Mk
Построим множества N = {A, B, M} и N" ={A, M, S}.
Правила (4) и (5) содержат символы из N. Для
правила (4) множество P1 = {M A}. Для правила (5)
множество P2 = {SMk, Sk} (M принадлежит N").
Правило (2) будет добавлено в результате
выполнения шага 3 алгоритма.
• Результирующая грамматика имеет вид G'
=(N", , P', S), где схему P' образуют правила
• (1) A  c
• (2) M A
• (3) S  Mk
• (4) S  k
Определение 8.4
• Правила вида AB (здесь A и B нетерминальные символы грамматики)
называют цепными.
• Легко видеть, что иногда грамматика может
стать грамматикой с цепными правилами в
результате выполнения алгоритма 8.4.
Алгоритм 8.5
• . Устранение цепных правил.
• Вход:
КС-грамматика G без -правил.
• Выход:
Эквивалентная КС-грамматика G без правил и без
цепных
правил.
• Метод.
• 1) Для каждого AN построить NA=B  A*B
следующим образом :
• а) положить N0=A и i=1,
• б) положить Ni = Ni-1  C BC  P & B Ni-1,
• в) если Ni  Ni –1, положить i=i+1 и повторить шаг б);
в противном случае положить NA = Ni .
• Заметим, что в результате построения некоторые из
множеств NA будут содержать единственный элемент
A.
• 2) Построить P следующим образом: включить в P
правило A, если B принадлежит P и не
является цепным правилом, а B NA. Отметим, что в
данном случае исходное не цепное правило B
также станет элементом множества P (так как может
иметь место B = A и, кроме того, по построению A 
NA).
• 3) Удалить из P все правила вида B, где B
недостижим из S.
• 4) Положить G=( N, , P, S), где N = {A  A   P}.
•
•
•
•
•
•
•
•
•
•
•
•
Пример 8.8. Рассмотрим грамматику со схемой
E  E+T T
T  T*F  F
F  (E)  a
На шаге (1) будут построены множества :
NE =E, T, F
NT = T, F
NF =F
После шага (2) множество P станет таким:
EE+TT*F  (E) a
TT*F  (E) a
F(E) a
• Поскольку все нетерминальные символы
достижимы из E, то в результате шага (3)
множество P не изменится.
• Пример 8.9. Рассмотрим грамматику со схемой
• SM
• MKA
• KP
• Pab
• Any
• На шаге (1) будут построены множества :
• NS =S, M
• NM =M
• NK =K,P
• NP = {P}
• NA = {A}
После шага (2) множество P станет таким:
S  KA
M  KA
K  ab
P  ab
A  ny
Нетерминальные символы M и P не достижимы из
S, поэтому в результате шага (3) правила M  KA
и P  ab будут удалены из множества P.
• Результирующая грамматика будет иметь вид
({S,K,A}, {a,b,n,y}, { S  KA, K  ab, A  ny}, S).
•
•
•
•
•
•
•
Теорема 8.2
• Грамматика G', которую строит алгоритм 8.5, не
имеет цепных правил и L(G) =L(G').
• Доказательство. Непосредственно видно, что
алгоритм 8.5 дает грамматику без цепных правил.
Докажем, что обе грамматики эквивалентны.
• Вначале покажем, что имеет место L(G')  L(G).
Пусть w  L(G'). Тогда в грамматике G' существует
вывод S  0  1...  n = w. Если при переходе
от i к i+1 применяется правило A  , то
существует такой символ B  N (возможно,
совпадающий с A), что A *G B и B *G . Таким
образом, A *G  и i *G i+1. Отсюда следует, что
S *G w и w  L(G). Следовательно, L(G')  L(G).
• Теперь покажем, что имеет место L(G)  L(G'). Пусть
w  L(G) и S= 0  1...  n = w - левый вывод
цепочки w в грамматике G. Можно найти
последовательность номеров шагов i1, i2,..., ik,
состоящую в точности из тех номеров j, для которых
на шаге j-1  j применяется не цепное правило.
Не цепное правило также применяется на последнем
шаге, так как вывод терминальной цепочки не может
заканчиваться цепным правилом. Поскольку мы
рассматриваем левый вывод, то последовательные
применения цепных правил заменяют символ,
занимающий одну и ту же позицию в левовыводимых
цепочках. Поэтому можно построить вывод S *G'
i1*G' i2*G' ... *G' ik = w. Таким образом, w 
L(G') и L(G)  L(G'). Теорема доказана.
Определение 8.5
• КС грамматика G = (N, , P, S) называется
грамматикой без циклов, если в ней нет
выводов A + A для AN.
• Устранить циклы в грамматике можно
посредством применения алгоритма 8.5, так
как причиной циклов могут быть цепные
правила вида A  A либо группы правил A 
A1, A1  A2,..., Ak  A.
Определение 8.6
• Грамматика G называется приведенной, если
она не содержит циклов, в ней нет -правил,
бесполезных и недостижимых символов.
Определение 8.7
• Назовем A-правилом правило, левая часть
которого есть A.
Лемма 8.1
• Пусть G =(N, , P, S) - КС-грамматика и схема
P содержит правило A  B, где B  N, а 
 (N )* и   (N  )*. Пусть B  1 2
...k - все B-правила этой грамматики. Пусть
G' =(N, , P', S), где P' = P \ {A B}  {A
1, A 2,..., A k}. Тогда L(G) =
L(G').
Задание 11
• Привести пример грамматики, содержащей
цепные правила, -правила (отличные от
правила S  ), бесполезные и
недостижимые символы. Показать, что язык,
порождаемый грамматикой, не пуст.
Построить приведенную грамматику,
эквивалентную исходной.
Download