Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Glava11 r.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
451 Кб
Скачать
☆

Алгоритм устранения левой рекурсии

Условие: дана КС-грамматика G(VT,VN,P,S), необходимо построить эквивалентную ей нелеворекурсивную грамматику G'(VN',VT,P',S'): L(G) = L(G').

Алгоритм преобразования работает с множеством правил исходной грамматики Р, множеством нетерминальных символов VN и двумя переменными счетчиками: i и j.

Шаг 1. Обозначим нетерминальные символы грамматики так: VN = {А1,А2,...,АП}. i := 1.

Шаг 2. Рассмотрим правила для символа aj. Если эти правила не содержат левой рекурсии, то перенесем их во множество правил Р' без изменений, а символ aj добавим во множество нетерминальных символов VN'.

Иначе запишем правила для aj в виде aj -» AiaI|Aiaβ|...|Aiam|β1|β2|...|Pp, где Vj I <j < β ни одна из цепочек pj не начинается с символов Аk, таких, что k < i.

Вместо этого правила во множество Р' запишем два правила вида:

Символы Ai и aj' включаем во множество VN'.

Теперь все правила для aj начинаются либо с терминального символа, либо с нетерминального символа Ak, такого, что k > i.

Шаг 3. Если i = n, то грамматика G' построена, иначе i:- i+1, j := 1 и перейти к шагу 4.

Шаг 4. Для символа aj во множестве правил Р' заменить все правила вида Aj->Aja, где aE(VTuVN)*, на правила вида Ai->Pia|β2a...|βma, причем Aj->β1|β2|...|βm — все правила для символа aj.

Так как правая часть правил Aj->β1|β2|...|βm уже начинается с терминального символа или нетерминального символа Ak, k > j, то и правая часть правил для символа aj будет удовлетворять этому условию.

Шаг 5. Если j - i-1, то перейти к шагу 2, иначе j := j+1 и перейти к шагу 4.

Шаг 6. Целевым символом грамматики G' становится символ А^, соответствующий символу S исходной грамматики G.

Рассмотрим в качестве примера грамматику для арифметических выражений над символами «а» и «b» G({+,-,/,*,а,b}, {S.T.E}, Р, S):

Эта грамматика является леворекурсивной. Построим эквивалентную ей нелеворекурсивную грамматику G'.

Шаг 1. Обозначим VN = {Аь А2, А3}. i := 1. Тогда правила грамматики G будут иметь вид:

Шаг 2. Для А1 имеем правила А1->А1+А2|А1-А2|А2. Их можно записать в виде А1-»A1a1|A1a2|β1, где a1 = + A2, a2 = -A2, βi = A2.

Запишем новые правила для множества Р':

Добавив эти правила в Р', а символы At и А1’ во множество нетерминальных символов, получим: VN' = {Aj.Aj1}.

Шаг 3. i = 1 < 3. Построение не закончено: i := i+1 = 2, j := 1.

Шаг 4. Для символа А2 во множестве правил Р' нет правила вида А2->А1а, поэтому на этом шаге никаких действий не выполняем.

Шаг 5. j = 1 = i-1, переходим опять к шагу 2.

Шаг 2. Для А2 имеем правила А2-»А2*А31А2/А31А3. Их можно записать в виде А2-» -»А2а, |А2а21 pj, где а! = *А3, а2 = /А3, pj = А3.

Запишем новые правила для множества Р':

Добавим эти правила в Р', а символы А2 и А2' во множество нетерминальных символов, получим: VN' = {А1,А1',А2(А2'}.

Шаг 3. i = 2 < 3. Построение не закончено: i := i+1 = 3, j := 1.

Шаг 4. Для символа А3 во множестве правил Р' нет правила вида A3-»Aia, поэтому на этом шаге никаких действий не выполняем.

Шаг 5. j - 1 < i-1, j := j+1 = 2, переходим к шагу 4.

Шаг 4. Для символа А3 во множестве правил Р' нет правила вида А3-»А2а, поэтому на этом шаге никаких действий не выполняем.

Шаг 5. j - 2 - i-1, переходим опять к шагу 2.

Шаг 2. Для А3 имеем правила А3 -» (А1) | а | b. Эти правила не содержат левой рекурсии. Переносим их в Р', а символ А3 добавляем в VN'. Получим: VN' = -s {А1,А1',А2,А2',Аз}.

Шаг 3. i = 3 = 3. Построение грамматики G' закончено.

В результате выполнения алгоритма преобразования получили нелеворекурсивную грамматику G({+,-,/,*,а,b}, {А1,A1’,A2,A2;,A3}, Р', A1) с правилами:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]