Синтаксичний аналіз без повернення назад
При виводу ланцюжка ω в G на кожному кроку безпосереднього виведення коли ми беремо до уваги виділений нами нетермінал (в залежності від стратегії виведення), виникає питання, яку альтернативу для використати. З точки зору практики, нас цікавить така стратегія виведення
в граматиці
, коли кожний наступний крок безпосереднього виведення наближав би нас до мети. Ця стратегія дасть можливість виконати виведення
в
за час пропорційний
, де
. Зрозуміло, що не маючи інформації про структуру
, досягнути вибраної нами мети в більшості випадків неможливо. Але ж тримати інформацію про весь ланцюжок
також недопустимо. З точки зору практики, отримати потрібний результат розумно при наявності локальної інформації, наприклад,
поточних вхідних лексем програми (
— наперед фіксоване число) достатньо для організації виведення
в
за час пропорційний
. З точки зору синтаксичного аналізу ланцюжка
мова ведеться про наступну ситуацію:
S
![]() | ![]() |
ω1 A ω2
![]() | ![]() |
ω1 X Y
Мал. 5
Зафіксуємо стратегію виводу: далі будемо розглядати лише лівосторонню стратегію виводу в
. Тоді:
- (
— перший зліва направо нетермінал);
- - термінальна частина ланцюжка
, яку вже виведено (проаналізована частина ланцюжка);
- результат , який потрібно ще вивести, виводиться з ланцюжка
;
- щоб зробити вірний крок виведення (без повернення назад) нам було б достатньо поточних вхідних символів з непроаналізованої частини програми
.
Сформульовані нами умови забезпечує клас -граматик.
Означення. КС-граматика називається
-граматикою для деякого фіксованого
, якщо дія двох лівосторонніх виводів виду:
1)
2) , для яких з
випливає, що
, де
.
Неформально, граматика буде
-граматикою, якщо для ланцюжка
перших символів (за умови, що вони існують) решти непроаналізованого ланцюжка визначають, що з
існує не більше однієї альтернативи виведення ланцюжка, що починається з
та продовжується наступними
термінальними символами.
Означення.
Сформулюємо основні твердження стосовно класу -граматик:
1) Не існує алгоритма, який перевіряє належність КС-граматики класу -граматик.
2) Існує алгоритм, який для конкретного перевіряє, чи є задана граматика
-граматикою.
3) Якщо граматика є -граматикою, то вона є
-граматикою, (
).
4) Клас -граматик — це підклас КС-граматик, який не покриває його.
Продемонструємо на прикладі справедливість твердження 4. Розглянемо граматику з наступною схемою
:
Мова, яку породжує наведена вище граматика . Візьмемо виведення наступного ланцюжка
; за означенням LL(K)-граматики
, тоді
маємо
Таким чином, КС-граматика не може бути
-граматикою для жодного
. Як результат, КС-граматика
, яка має ліворекурсивний нетермінал
( нетермінал
називається ліворекурсивний, якщо в граматиці
існує вивід виду
), не може бути
-граматикою.
З практичної точки зору в більшості випадків ми будемо користуватися -граматиками. У класі
-граматик існує один цікавий підклас - це розподілені
-граматики.
Означення. -граматика називаються розподіленою, якщо вона задовольняю наступним умовам:
- у схемі граматики відсутні
-правила (правила виду
);
- для нетермінала праві частини
-правила починаються різними терміналами.
Для подальшого аналізу означення -граматики розглянемо алгоритм обчислення функції
.
Означення: Якщо , то
, де
— бінарна операція над словарними множинами (мовами):
.
Висновок, якщо , де
, тоді
Очевидно, якщо , то
при
. Розглянемо алгоритм пошуку
Алгоритм. Пошук множини .
Визначимо значення функції для кожного
.
П1. для всіх
.
П2.
в інших випадках - невизначено.
Пn.
в інших випадках - невизначено.
Пm. для всіх
.
Очевидно, що:
- послідовність — монотонно зростаюча;
- — послідовність, обмежена зверху.
Тоді покладемо для кожного
.
Приклад: Знайти множину Firstk(Ai) для нетерміналів граматики з наступною схемою правил:
S -> BA
A -> +BA | ε
B -> DC
C -> *DC | ε
D -> (S) | a
Нехай k=2.
Fn\Ai | S | A | B | C | D |
F0 | -- | { ε } | -- | { ε } | {a} |
F1 | -- | { ε } | {a} | { ε, *a} | {a} |
F2 | {a} | {ε, +a} | {a, a*} | { ε, *a} | {a} |
F3 | {a, a+, a*} | {ε, +a} | {a, a*} | { ε, *a} | {a, (a} |
F4 | {a, a+, a*} | {ε, +a} | {a, a*, (a} | { ε, *a, *(} | {a, (a} |
F5 | {a, a+, a*, (a} | {ε, +a, +(} | {a, a*, (a} | { ε, *a, *(} | {a, (a} |
F6 | {a, a+, a*, (a} | {ε, +a, +(} | {a, a*, (a} | { ε, *a, *(} | {a, (a, ((} |
F7 | {a, a+, a*, (a} | {ε, +a, +(} | {a, a*, (a, ((} | { ε, *a, *(} | {a, (a, ((} |
F8 | {a, a+, a*, (a, ((} | {ε, +a, +(} | {a, a*,(a, ((} | { ε, *a, *(} | {a, (a, ((} |
F9 | {a, a+, a*, (a, ((} | {ε, +a, +(} | {a, a*, (a, ((} | { ε, *a, *(} | {a, (a, ((} |
Скористаємося означенням сформулюємо необхідні й достатні умови, за яких КС-граматика буде
-граматикою:
для довільного виводу в граматиці G виду та правила
:
(1)
Вище сформульована умова для -граматик може бути перефразована з урахуванням визначення множини
:
для довільного виводу в граматиці виду
та правила
:
, де
(2).
Оскільки , то умова (2) є конструктивною умовою і може бути використана для перевірки, чи КС-граматика є
-граматикою для фіксованого
.
Означення: КС-граматика називається сильною -граматикою, якщо для А-правила виду
задовольняється умова:
,
де визначається так:
Операції та
можна узагальнити для словарної множини
, тоді:
.
Без доведення зафіксуємо наступні твердження:
- кожна -граматика є сильною
-граматикою;
- існують -граматики (k>1), які не є сильними
-граматиками.
На прикладі продемонструємо останнє твердження. Нехай граматика визначена наступними правилами:
,
.
Відповідні множини ,
,
,
.
Перевіримо умову для сильної -граматики:
а) виконаємо перевірку -умови для правила
б) виконаємо перевірку -умови для правила
Висновок: вище наведена граматика не є сильною -граматикою. Перевіримо цю ж граматику на властивість
-граматики. Тут ми маємо два різні варіанти виводу з S:
а)
б)
Висновок: наведена вище граматика є -граматикою.
Алгоритм. Обчислення .
Для побудови алгоритму пошуку множини розглянемо наступні приклади на синтаксичному дереві, які дозволять перейти до узагальнень.Подивимося на синтаксичне дерево висоти 1 для правила
S
ω1 A ω2
Мал. 6
Тоді .
Далі розглянемо дерево висоти 2:
S
![]() |
ω1 AJ ω2
![]() | ![]() |
ω3 A ω4
Мал. 7.
Тоді . В силу вищесказаного, будемо знаходити значення функції
, тобто будемо розглядати всілякі дерева, які можна побудувати, починаючи з аксіоми
.
П0. . Очевидно, за 0 кроків ми виведемо S, після якої знаходиться
. У інших випадках
— невизначено
.
П1. . В інших випадках
— невизначено.
….
Пn . В інших випадках
— невизначено.
….
Настане крок Пm, коли ,
.
Тоді покладемо для кожного
.
Очевидно, що:
- послідовність монотонно зростаюча;
- послідовність обмежена зверху.
До того, як перевірити граматику на -властивість необхідно перевірити її на наявність ліворекурсивних нетерміналів та спробувати уникнути лівої рекурсії.
Означення: Нетермінал КС-граматики
називається
-нетерміналом, якщо
.
Алгоритм.Пошук -нетерміналів:
….
…. Пn
Тоді множина — множина
-нетерміналів.
Приклад. Для граматики G з схемою правил Р знайдемо множину -нетерміналів:
=
Таким чином, множина -нетерміналів для наведеної вище граматики -
Алгоритм.Тестування нетермінала на ліву рекурсію. Для кожного нетермінала Аi побудуємо наступну послідовність множин S0, S1, ….
, починаємо з нетерміналу Аi.
….
….
Тоді якщо , то
— ліворекурсивний нетермінал.
Приклад. Для граматики G з схемою правил Р знайдемо множину ліворекурсивних нетерміналів:
1. Виконаємо процедуру тестування для кожного нетермінала окремо:
- наприклад, для нетермінала S:
Запропонуємо декілька прийомів, що дають можливість при побудові граматик уникнути лівої рекурсії. Розглянемо граматику зі схемою правил
, яка має ліворекурсивний нетермінал
. Замінимо схему правил новою схемою з трьома правилами
.
Приклад: Для граматики G з схемою правил Р для кожного нетермінала знайдемо множину (k=1):
S -> BA
A -> +BA | ε
B -> DC
C -> *DC | ε
D -> (S) | a
З прикладу, що наведено раніше множини First1(A) ,будуть такими:
First1(S)= First1(B)= First1(D)={(,a}, First1(A)={+, ε }, First1(C)={*, ε }.
δn\Ai | S | A | B | C | D |
δ0 | { ε } | -- | -- | -- | -- |
δ 1 | { ε } | { ε } | {+, ε } | -- | -- |
δ 2 | { ε } | {ε} | {+, ε } | {+, ε } | |
δ 3 | { ε } | {ε} | {+, ε } | {+, ε } | {*, +, ε } |
δ 4 | { ε, ) } | {ε} | {+, ε } | {+, ε } | {*, +, ε } |
δ 5 | { ε, ) } | {ε, )} | {+, ε } | {+, ε, )} | {*, +, ε } |
δ 6 | { ε, ) } | {ε, )} | {+, ε , )} | {+, ε } | {*, +, ε , )} |
δ 7 | { ε, ) } | {ε, )} | {+, ε , )} | {+, ε , )} | {*, +, ε , )} |
Таким чином, Follow1(S)= { ε, ) }, Follow1(A)= {ε, )}, Follow1(B)= {+, ε, )}, Follow1(C)= {+, ε , )}, Follow1(D)= {*, +, ε , )}.