В данном разделе приводятся такие преобразования грамматик, которые не выводят нас из класса эквивалентности, т.е. грамматика G1 таким образом преобразуется в грамматику G2, чтобы L(G1)=L(G2).
9.1 Устранение непроизводящих правил.
Непроизводящими правилами грамматики начинаются правила, применение которых никогда не приводит к построению терминальных цепочек.
Например, рассмотри правила для нетерминала А
А®А А½ В А
В этом случае, появившись в цепочке, нетерминал А никогда не будет заменен терминальной цепочкой (имеется в виду, что других правил для А нет). Естественно, в реальности ситуации бывают не столь простые. Алгоритм устранения непроизводящих нетерминалов:
- Построение множества производящих нетерминалов NR:
- Строится множество NR1 = {A/ A®bj,bjÎVT}
- Последовательно строятся множества NRi+1={ A/ A®bj,bjÎ(NRiÈVT)*} до тех пор, пока получим NRi+1= NRi или же NRi= VN. Тогда NR = NRi.
- Исключаем из грамматики все правила, в правых частях которых нетерминалы из VN\ NR.
- Исключаем из грамматики правые части правил, в которых присутствуют нетерминалы из VN\ NR.
Например, рассмотрим грамматику G с множеством правил
|
|
S® AB½BC
A® AA½AB
B® bB½a
С®сС½d ½AC
Построим множество NR. NR1={B,C}, NR2={S, B, C}, NR3= NR2= NR.
Преобразованная грамматика примет вид:
S® BC
B® bB½a
С®сС½d
9.2. Устранение недостижимых нетерминалов.
Недостижимыми нетерминалами называются нетерминалы, которые никогда не могут быть построены при построении вывода, начиная с начального символа грамматики. Следует отметить, что такие нетерминалы в грамматиках встречаются в основном тогда, когда исключены некоторые непроизводящие символы, т.е. недостижимым нетерминал становится чаще всего после исключения некоторых непроизводящих симовлов. Например, если в грамматике для нетерминала А правила А®А А½ В А, и нетерминал В не встречается в других правых частях правил грамматики, то в этом случае, после устранения нетерминала А нетерминал В становится недостижимым, и, следовательно, его можно исключить из грамматики без изменения порождаемого ей языка. Построение множества недостижимых нетерминалов похоже на построение множества непроизводящих нетерминалов: мы строим множество всех достижимых нетерминалов, а затем исключаем все остальные нетерминалы грамматики. Алгоритм построения грамматики, в которой используются только достижимые нетерминалы (множество достижимых нетерминалов –D), выглядит следующим образом:
Пусть дана грамматика G=< VT,VN, S, R>, строится эквивалентная грамматика без непроизводящих символов G’ =< VT,VN’, S, R’>.
1. Начальное значение D0=S.
2. Итерационное построение множества D: Di+1= DiÈ{A/B®aAbÎR&BÎ Di}
|
|
3. Построение продолжается, до тех пор, пока Di+1= Di или Di+1= VN, в обоих случаях VN’= Di+1,
R’={ Ri / Ri=(A®j), AÎ VN’,jÎ(VN’È VT) * }
Построенная грамматика не содержит недостижимых нетерминалов.
Например, рассмотрим грамматику G с множеством правил
S® A C ½B C
A® AD½ DF
D® aA ½ D A
F® b F½l
B® bB½a
С®сС½d
Тогда здесь A и D непроизводящие нетерминалы, после их устранения нетерминал F становится недостижимым, поэтому нетерминалы A, D и F могут быть исключены из грамматики с сохранением языка, порождаемого грамматикой.
9.3. Устранение l - правил
Устранение l - правил связано с исключением построения цепочек, которые после преобразований превращаются в пустую цепочку. Цель такого преобразования грамматики – если в грамматике строится пустая цепочка, то она строится в результате первого шага построения. Применение любого из оставшихся правил приводит к построению непустых цепочек, более того, цепочка, построенная из каждого из нетерминала, состоит не менее чем из одного терминального символа.
Пусть дана грамматика G=< VT,VN, S, R>, строится эквивалентная грамматика G’ =< VT,VN’, S, R’>.
1. Построить множество Nl = { A / A Þ+ l } - множество нетерминальных символов, из которых возможен вывод пустой цепочки. Множество Nl строится итерационно. На первом шаге строится Nl0.
Nl0 = { B / B ® l Î R}
Пусть построено Nl1, Nl2,..., Nli, (i ³ 0). Тогда Nli+1 = Nli È{ B / B ® j Î R & j Î (Nli)* }.
Если на очередном шаге Nli+1 = Nli, то искомое множество Nl найдено (Nl = Nli ).
2. Построить R’ — множество правил эквивалентной грамматики так, что:
a) Если A®a0 B1 a1 B2 ... Bk ak Î R, k ³ 0 и Bi Î Nl для 0 £ i £ k, но ни один символ в цепочках aj, 1 £ j £ k не содержит символа из Nl, то включить в R’ все правила вида
A ® a0X1a1X2...Xkak
Xi либо Bi, либо l (при этом правило A ® l не включать; это могло бы произойти, если все ai = l).
b) если S Î Nl, включить в R’ также правило S’® S½l где S’ - новый начальный символ.
Таким образом, любая КС—грамматика может быть приведена к виду, когда R не содержит l -правил, либо есть точно одно правило S’ ® l и S’ не встречается в правых частях остальных правил из R. Такие грамматики будем называть неукорачивающими.
Например, пусть дана грамматика G с множеством правил
S®A B½ BC
A® aAb ½l
B® dB½c
C® CC½Ac½l
Nl0= {A, C}
Nl1= {A, C}= Nl. Поскольку lÏL(G) (SÏ Nl), правила грамматики примут вид
S®A B ½B½ BC
A® aAb ½ab
B® dB½c
C® CC½Ac½a½ c
Б. Устранение правил А ® В (цепных правил)
Применение цепных правил приводит к увеличению длины ветвей синтаксического дерева, исключение цепных правил часто приводит к большей «прозрачности» грамматики и уменьшению длины выводов, которые можно построить. Алгоритм исключения цепных правил:
1. Для каждого AÎ VN построить NA = { B / A ® B },т.е. множество нетерминальных символов, выводимых из данного символа. Процедура построения следующая:
а) положить NA0 ={A}.
б) пусть построены NA0, NA1... NAi . Тогда
NAi+1 = { C / B ® C Î R & B Î NAi } È NA0.
Если на очередном шаге NAi+1 = NAi, то положить NA = NAi.
2. Построить R’ (множество правил эквивалентной грамматики) так: если B ® a Î R и не является цепным правилом, то включить в R’ правила A ® a. для всех таких A, что
B Î NA.
Рассмотрим пример. Пусть множество правил грамматики имеет вид:
S®T+S½T
T® M*T½M
M® (S)½ i
Простроим для данной грамматики множества NA
NS ={S, T, M}
NT = {T, M}
NM = {M}
После преобразования грамматики она примет вид:
S®T+S½ M*T½(S)½ i
T® M*T ½(S)½ i
M® (S)½ i
В данном случае преобразование грамматики не привело к её упрощению, но построенные синтаксические деревья будут иметь меньшую глубину, и построение дерева будет происходить быстрее.
Грамматика называется неукорачивающей, если для любого правила грамматики j®y выполняется½j½£½y½. Такое определение применимо как к КС-грамматикам, так и к КЗ-грамматикам. А-грамматика так же может быть неукорачивающей. Для КС и А-грамматик необходимым и достаточным условием принадлежности к классу неукорачивающих грамматик является отсутствие в них l-правил.
|
|
Грамматика называется приведенной, если она неукорачивающая и не содержит непроизводящих символов.
Поэтому, если lÏL(G), то существует приведенная грамматика G1, такая, что L(G1)=L(G).
В случае же lÎL(G), существует эквивалентная грамматика с единственным укорачивающим правилом.