- •Обзорная лекция по курсу «языки программирования и методы трансляции»
- •Основная литература
- •1 Описание языка программирования
- •2 Введение в трансляцию
- •3 Способы описания языка
- •4 Формальные языки и грамматики. Основные термины и определения
- •5 Порождающие грамматики (Грамматики н.Хомского1)
- •6 Классификация формальных грамматик
- •7.1. Механизмы распознавания и преобразования
- •7.2 Конечные автоматы
- •7 Автоматные грамматики и конечные автоматы
- •7.3 Способы задания конечных автоматов
- •Контекстно-свободные грамматики и языки
- •Проверка существования языка
- •Удаление бесполезных символов грамматики
- •Эквивалентные преобразования кс-грамматик
- •9.1 Устранение цепных правил
- •Удаление произвольного правила
- •9.3 Левая факторизация правил
- •9.4 Преобразование к нормальной форме Хомского
- •Распознающий автомат для кс- языков (автомат с магазинной памятью)
- •Разнозновидности мп-автоматов
- •11 Методы синтаксического анализа
- •Нисходящий разбор
- •Восходящий разбор
- •12 Генерация внутреннего представления программ
- •12.1 Польская запись
- •2 Алгоритм перевода на промежуточный язык
- •2.1 Полиз как промежуточный язык
9.3 Левая факторизация правил
Левую факторизацию можно выполнять для правил грамматики, определяющих один и тот же нетерминал и имеющих одинаковое начало (префикс) правых частей. Цель такого преобразования – устранение одинаковых префиксов. При проведении левой факторизации выполняются действия, подобные вынесению за скобки общего левого множителя в алгебраических выражениях. Алгоритм преобразования состоит в следующем:
Вход: КС-грамматика G=(N, T, P, S) без -правил.
Выход: Эквивалентная КС-грамматика G’=(N, T, P’, S) без одинаковых префиксов в правых частях, определяющих нетерминал.
Записать все правила для нетерминала X, имеющие одинаковые префиксы , в виде одного правила с альтернативами (вариантами):
X 1|2|…|n| , 1, 2, …,n
Вынести за скобки влево префикс каждой строки-альтернативы:
X (1| 2|…| n|) , 1, 2, …,n
Обозначить новым нетерминалом Y выражение, оставшееся в скобках:
X Y, Y 1| 2|…| n
Пополнить множество нетерминалов новым нетерминалом Y и заменить правила, подвергшиеся факторизации, новыми правилами для X и Y.
Повторить п.1-4 для всех нетерминалов грамматики, для которых это возможно и нобходимо.
Пример. Ниже показана левая факторизация правил
1) SaSb 2) SaSc 3) Sd грамматики G=({S}, {a, b, c}, P, S)
Шаг алгоритма |
Действия и результаты |
1 |
SaSb |aSc |
2 |
SaS(b |c) |
3 |
SaSW W b |c |
4 |
G’=({S, W}, {a, b, c}, P’, S) P’={ SaSW Sd W b |c } |
5 |
Других объектов факторизации нет |
Пример. Выполнить левую факторизацию правил КС-грамматики
1) SabSa 2) SaaAb 3) Sb 4) AbaAb 5) Ab грамматики G=({S,A}, {a, b}, P, S)
Шаг алгоритма |
Действия и результаты |
1 |
SabSa| aaAb |
2 |
Sa(bSa| aAb) |
3 |
SaW Sb WbSa W aAb |
4 |
AbaAb |b |
5 |
Ab(aAb |) |
6 |
AbZ Z aAb Z |
7 |
Грамматика после левой факторизации имеет вид: G’=({S, A, W, Z}, {a, b}, P’, S) P’={ SaW Sb WbSa W aAb, AbZ Z aAb Z }, S) |
8 |
Других объектов факторизации нет |
9.4 Преобразование к нормальной форме Хомского
Каждая КС-грамматика G=(N, T, P, S) эквивалентна грамматике в нормальной форме Хомского с правилами вида:
АВС, где А, В, С N;
Аa, где а Т;
S, если L(G), причем S не встречается в правых частях правил.
Дерево разбора любой строки языка в такой грамматике будет бинарным. Преобразование к нормальной форме Хомского (НФХ) полезно, когда требуется простая структура КС-языка. Оно выполняется путем сокращения количества символов правой части правила за счет введения новых обозначений (нетерминалов). Предварительно нужно привести исходную КС-грамматику.
Примечание: КС-грамматика обладает свойствами приведенной грамматики, если она не имеет циклов, -правил и бесполезных символов. Отсутствие циклов означает, что в грамматике невозможны выводы вида А+А, где А N.
Вход: КС-грамматика G=(N, T, P, S)
Выход: Эквивалентная КС-грамматика G’=(N’, T, P’, S) в НФХ
Включить в P’ каждое правило вида 2, т.е. (Аa ) Р;
Включить в P’ каждое правило вида 1, т.е. (АВС) Р;
Включить в P’ каждое правило вида 3, т.е. (S) Р (если оно есть в Р);
Для каждого правила (АX1…Xk) Р, где k>2, включить в P’ правила:
АX1’<X2…Xk>
<X2…Xk> X2’<X3…Xk>
. . .
<Xk-2 Xk-1Xk> Xk-2’< Xk-1Xk>
< Xk-1Xk> Xk-1’X’k
г
де
<Xi…Xk>
- новый нетерминал
Xi , если Xi N
Xi’= X’i , если Xi T
Для каждого правила (АX1X2) Р, где хотя бы один из символов X1 и X2 является терминалом, включить в P’ согласно обозначениям правило (АX’1X’2)
Для каждого нового нетерминала вида X’, введенного в п.4 или в п.5, согласно обозначениям, включить в P’ правило X’X, где XT
Пополнить множество нетерминалов V’N = V’ {новые нетерминалы}
При реализации алгоритма полезно иметь таблицу для обозначения терминалов и таблицу для обозначения строк из двух и более символов.
Пример. Преобразование в НФХ грамматики с правилами
SaAВ | BA
АВBB|a
BAS|b
Шаг алгоритма |
Действия и результаты |
1 |
P’={ Аa, B|b} |
2 |
P’={ Аa, B|b} { S BA , BAS } |
3 |
Правила S нет |
4 |
1) SaAВ Терминал а обозначаем N1 Строка АВ обозначаем N2 Новые правила: S N1 N2 , N2 АВ 2) АВВВ Строка ВВ обозначаем N3 Новые правила: А ВN3 , N3 ВВ |
5 |
Таких правил нет |
6 |
Правило N1 а помещаем в P’: { S N1 N2 | ВА , А ВN3| a, BAS| b, N2 АВ, N3 ВВ} { N1 а } |
7 |
N’=N{обозначения терминалов и строк}={S, A, B, N1, N2 , N3} |
