- •Введение
- •Формальные грамматики. Выводы Основные понятия
- •Способы задания языков
- •Операции над языками
- •Формальные грамматики. Выводы
- •Преобразования кс-грамматик Основные понятия
- •Устранение лишних символов
- •Исключение лишних правил
- •Исключение -правил
- •Устранение цепных правил
- •Выделение нетерминала
- •Левая факторизация
- •Устранение левой рекурсии
- •Устранение правой рекурсии
- •Нормальная форма Хомского
- •Нормальная форма Грейбах
- •Операторная кс-грамматика
- •Регулярные языки и конечные распознаватели Правосторонние грамматики
- •Левосторонние грамматики
- •Связь правосторонних и левосторонних грамматик
- •Преобразование кс-грамматики произвольного вида в правостороннюю
- •Конечные распознаватели. Основные понятия
- •Преобразование недетерминированных конечных распознавателей с -переходами в детерминированные
- •Эквивалентность состояний конечных детерминированных распознавателей
- •Эквивалентность конечных детерминированных распознавателей
- •Минимизация конечных детерминированных распознавателей
- •Регулярные множества и регулярные выражения
- •Регулярные выражения и конечные распознаватели
- •Получение регулярного выражения из конечного распознавателя
- •Построение конечного распознавателя по регулярному выражению
- •Конечные распознаватели и регулярные грамматики
- •Получение грамматики из конечного распознавателя
- •Построение конечных распознавателей по регулярным грамматикам
- •Ещё один способ взаимного преобразования право- и левосторонних грамматик
- •Программная реализация конечных детерминированных распознавателей
- •Лексический анализ
- •Принципы построения лексических анализаторов
- •Определение границ лексем
- •Выполнение действий, связанных с лексемами
- •Выделение ключевых слов
- •Программная реализация лексических анализаторов
- •Глава 3. Синтаксический анализ
- •3.1. Автомат с магазинной памятью
- •3.2. Таблично-управляемый предсказывающий разбор
- •3.2.1. Алгоритм разбора сверху-вниз
- •3.2.2. Множества first и follow
- •3.2.3. Конструирование таблиц предсказывающего анализатора
- •3.2.4. Ll(1)-грамматики
- •3.2.7. Рекурсивный спуск
- •3.3. Разбор снизу-вверх типа сдвиг-свертка
- •3.3.1. Основа
- •3.3.2. Lr(k)-анализаторы
- •3.3.4. Конфликты разбора типа сдвиг-свертка
Преобразование кс-грамматики произвольного вида в правостороннюю
Регулярный язык может быть задан КС-грамматикой произвольного вида, т.е. без ограничений на правую часть правил. В этом случае исходную грамматику можно преобразовать в регулярную, например в правостороннюю. Если же исходная грамматика порождает нерегулярный язык, то её нельзя преобразовать в правостороннюю с конечным числом правил.
Для преобразования КС-грамматики произвольного вида в правостороннюю, представим её в такой форме, что правая часть каждого правила начинается терминалом (см.’Нормальная форма Грейбах’). Такая грамматика может содержать правила вида АВ и А , где А и В – нетерминалы, - последовательность терминалов, удовлетворяющие правосторонней грамматике, и правила вида А , где - последовательность терминалов и нетерминалов, начинающаяся нетерминалом, содержащая более одного символа, которые неудовлетворяют правосторонней грамматике.
Рассмотрим возможную последовательность действий, позволяющую выразить правило вида А множеством правил, удовлетворяющих правосторонней грамматике.
Пусть в грамматике есть правило А11 . На первом шаге заменим его правилом, удовлетворяющим правосторонней грамматике А1N1 , а нетерминал N1 определим правилом N11 . Это правило неудовлетворяет правосторонней грамматике, т.к. правая часть (край) начинается нетерминалом, за которым следуют другие символы (по условию). Теперь выполним замену края. При этом край заменяется правыми частями всех правил, его определяющих. Пусть среди них будет правило с номером i1 . В результате замены края по правилу с номером i1 можем получить либо правило N122 , либо правило N12В , удовлетворяющее правосторонней грамматике. Допустим получено правило N122 .
На втором шаге выполним аналогичные действия: заменим N122 правилом N12N2 , определим N22 , выполним замену края и применяя правило с номером i2 , получим правило N233 и т.д.
На n-ом шаге при замене края в правиле Nnn по правилу с номером in получим правило Nnn+1n+1 . Далее заменим это правило на Nnn+1Nn+1 и определим Nn+1n+1 .
Если n+1=j , 1 j n , то правило Nnn+1n+1 можно заменить на Nnn+1Nj и новый нетерминал Nn+1 и правило Nn+1n+1 вводить не нужно. Т.о. процесс добавления новых нетерминалов и правил в данном направлении останавливается. Но, т.к. замена края выполняется по всем правилам, определяющим край, процесс добавления новых нетерминалов и правил может продолжаться по другим направлениям. Если этот процесс остановится по всем направлениям, то будет получена правосторонняя грамматика.
Если же n+1 и j , 1 j n , имеют общий префикс и n+1 представляет собой j , дополненную цепочкой , то в процессе преобразований можно снова применить последовательность правил ij, ij+1,…, in , в результате чего получим правило Nnk и k будет иметь общий префикс с j и содержать ещё одну цепочку . Повторное применение последовательности правил ij, ij+1,…, in приводит к добавлению цепочки в j . Это требует введения нового правила и процесс преобразования зацикливается, получить правостороннюю грамматику с конечным числом правил в этом случае нельзя.
Для обнаружения зацикливания будем строить и анализировать множество деревьев, вершины которых соответствуют вводимым правилам вида N . Если в процессе преобразований в результате замены края в правиле Njj по i-ому правилу получаем Njkk , которое заменяем на NjkNk и вводим правило Nkk , то в дереве из вершины с правилом Njj проводим дугу в вершину с правилом Nkk .
Если в дереве существует путь от вершины с правилом Njj до вершины с правилом Nmm , цепочки j и m имеют общий префикс и цепочка m получена из цепочки j добавлением (вставкой) непустой цепочки , то процесс преобразования зацикливается и получить правостороннюю грамматику с конечным числом правил нельзя.
Алгоритм преобразования КС-грамматики, правые части правил которой начинаются терминалом, в правостороннюю.
Вход: G – исходная грамматика.
Выход: G’ – правосторонняя грамматика.
1. Последовательно просмотреть все правила исходной грамматики. Правила вида АВ и А, удовлетворяющие правосторонней грамматике, включить в множество правил грамматики G’. Правила вида А , неудовлетворяющие правосторонней грамматике, обработать в соответствии с п.2.
2. Обработка правила вида А .
Если в деревеьях есть вершина с правилом Nm , то правило АNm включить в множество правил грамматики G’ , конец п.2.
Если в деревьях нет вершины с правилом Nm , то создать вершину (корень нового дерева) с правилом Nm , правило АNm включить в множество правил грамматики G’ и обработать вершины дерева (листья) в порядке их создания в соответствии с п.3.
3. Обработка вершины с правилом Nm .
Выполнить замену края. В результате получим множество правил, определяющих нетерминал Nm : Nmii . Каждое правило этого множества обработать в соответствии с п.4.
4. Обработка правила Nmii , полученного в п.3.
Если в деревеьях есть вершина с правилом Nki , то правило NmiNm включить в множество правил грамматики G’ , конец п.4.
Если в деревеьях нет вершины с правилом Nki , то создать вершину с правилом Nki , провести в неё дугу из вершины с правилом Nm (см. п.3) и правило NmiNm включить в множество правил грамматики G’. Если на пути отсозданной вершины (с правилом Nki ) к корню дерева есть вершина с правилом Npj , таким, что j и i имеют общий префикс и цепочка i получена из цепочки j добавлением (вставкой) непустой цепочки , то получить правостороннюю грамматику с конечным числом правил нельзя, конец алгоритма.
Ниже приведены примеры преобразования. Рядом с вершинами деревьев записаны множества правил, получаемых из правил вершин выполнением замены края.
Пример 1.
Исходная Деревья Правосторонняя
грамматика правил грамматика
S
aBc
N1cASc
SaN1
S
b
N1aBc
N1cN2
BcAS N1aN1
BaB N2bBSc N2bN3
A
bB
N2dSc
……….
Ad
……….
Правые части правил N1Bc (корень) и N3BSc (лист) имеют общий префикс (В) и правая часть правила N3BSc представляет собой правую часть правила N1Bc , дополненную символом S . Дальнейшие преобразования будут добавлять символ S в цепочку BSc , в результате чего будем получать бесконечное число правил вида NBS*c . Правостороннюю грамматику с конечным числом правил получить нельзя.
Пример 2.
Исходная Деревья Правосторонняя
грамматика правил грамматика
S
aABS
N1aBBS
SaN1
S
bB
N1cBaBS
N1aN2
AaB N1cN3
A
cBa
N3bBaBS
N2bN2
BbB N3daBS N2dN4
B
d
N3bN3
N2bBBS
N3daN4
N2dBS N4bN4
N4dS
N4bBS
SbB
N4dS AaB
AcN5
N5bBa N5bN5
N5da N5da
Характерной особенностью КС-грамматик, порождающих нерегулярный язык, является наличие самовложенных нетерминалов. Нетерминал А называется самовложенным, если существует вывод А*А , где и - непустые цепочки терминалов и нетерминалов. КС-грамматика произвольного вида, несодержащая самовложенных нетерминалов, порождает регулярный язык и применение к ней рассмотренного выше алгоритма всегда приводит к получению правосторонней грамматики с конечным числом правил.
Для нахождения самовложенных нетерминалов грамматики G , правые части правил которой начинаются терминалом, будем анализировать грамматику G’ , включающую в себя множество псевдоправил, соответствующих правилам грамматики G , содержащим хотя бы один нетерминал в правой части. Псевдоправило в правой части содержит один нетерминал, который может быть окружён символами . Каждому вхождению нетерминала в правую часть правила A грамматики G соответствует псевдоправило. Пусть правая часть правила A содержит нетерминал В. Если нетерминал В самый правый символ в цепочке , то ему соответствует псевдоправило АВ. Если же нетерминал В не самый правый символ в цепочке , то ему соответствует псевдоправило АВ . Символ в псевдоправиле заменяет всю непустую цепочку символов, расположенную перед или после рассматриваемого нетерминала в исходном правиле.
В грамматике G’ из каждого нетерминала можно вывести конечное множество (выводимых) псевдоцепочек, состоящих из нетерминала и не более двух, не стоящих рядом, символов . Определим множество псевдоцепочек, выводимых из нетерминала А , следующим образом:
- псевдоцепочка, состоящая из нетерминала А – выводимая;
- если псевдоцепочка выводима из нетерминала А , то псевдоцепочка , полученная из псевдоцепочки заменой входящего в неё нетерминала правой частью псевдоправила, содержащего в левой части этот нетерминал, и заменой каждой последовательности из двух символов одним символом - выводимая. Псевдоцепочка называется непосредственно выводимой из псевдоцепочки . Если псевдоцепочка А выводима в грамматике G’ из нетерминала А , то нетерминал А в грамматике G является самовложенным.
Для нахождения множества псевдоцкпочек, выводимых из нетерминала А , будем строить дерево, корень которого содержит нетерминал А , остальные вершины – псевдоцепочки, выводимые из нетерминала А , причём из вершины, содержащей псевдоцепочку , идёт дуга в вершину, содержащую псевдоцепочку , если непосредственно выводима из .
Алгоритм построения дерева выводимых псевдоцепочек из нетерминала А .
1. Создать корень дерева с нетерминалом А . Он же является листом. Обрабатывать листья дерева в порядке их создания в соответствии с п.2.
2. Пусть лист содержит псевдоцепочку с нетерминалом В и в грамматике G’ n псевдоправил, определяющих нетерминал В . Получить все псевдоцепочки i , i=1,n , непосредственно выводимые из псевдоцепочки . Если в дереве нет вершины, содержащей псевдоцепочку i , то создать вершину (лист) с псевдоцепочкой i и провести в неё дугу из обрабатываемой вершины с псевдоцепочкой .
Алгоритм нахождения самовложенных нетерминалов грамматики G, заданной в нормальной форме Грейбах.
1. Получить грамматику G’ , содержащую псевдоправила, соответствующие правилам грамматики G .
2. Последовательно обрабатывать нетерминалы грамматики G’ в соответствии с п.3.
3. Пусть А – обрабатываемый нетерминал. Построить дерево выводимых псевдоцепочек из нетерминала А (см. алгоритм выше). Если дерево содержит вершину с псевдоцепочкой А , то нетерминал А – самовложенный. (Если в процессе построения дерева на некотором шаге получена псевдоцепочка А , то дерево дальше не строить.)
Пример 1.
Исходная грамматика G Грамматика G’
S aBc SB
Sb BA
BcAS BS
BaB BB
AbB AB
Ad
Дерево выводимых псевдоцепочек из нетерминала S
Дерево выводимых псевдоцепочек из нетерминала S содержит псевдоцепочку S , следовательно, нетерминал S самовложенный.
Пример 2.
Исходная грамматика G Грамматика G’
S aABS SA
SbB SB
AaB SS
AcBa SB
BbB AB
Bd AB
BB
Дерево выводимых псевдоцепочек из нетерминала S
Д
ерево
выводимых псевдоцепочек из нетерминала
S не содержит псевдоцепочку S
, следовательно, нетерминал S
несамовложенный.
Дерево выводимых псевдоцепочек из нетерминала А
Дерево выводимых псевдоцепочек из нетерминала А не содержит псевдоцепочку А , следовательно, нетерминал А несамовложенный.
Дерево выводимых псевдоцепочек из нетерминала В
Дерево выводимых псевдоцепочек из нетерминала В не содержит псевдоцепочку А , следовательно, нетерминал В несамовложенный.
В грамматике G нет самовложенных нетерминалов, поэтому она порождает регулярный язык и может быть преобразована в правостороннюю.
КС-грамматика произвольного вида, имеющая самовложенные нетерминалы, порождает регулярный язык в том случае, если исключение некоторых правил приводит к отсутствию самовложенных нетерминалов и не изменяет порождаемого языка, но проверить это, в общем случае, невозможно в силу алгоритмической неразрешимости проблемы эквивалентности КС-языков.
Пример.
Грамматика G1 Грамматика G2
АаАс Ав
Ав АаА
АаА АвВ
АвВ ВсВ
ВсВ Вс
Вс
Грамматика G1 содержит самовложенный нетерминал А . Грамматика G2 получена из грамматики G1 исключением правила АаАс и не имеет самовложенных нетерминалов. Обе грамматики порождают один и тот же регулярный язык L={anbcm | n0 и m0} .
