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

5.2.3 Активні префікси

Префікси правосентенциальных форм, які зустрічаються в стеку ПЗ-аналізатора, називаються активними (viable prefixes). Еквівалентне визначення активного префікса полягає в тім, що це - префікс правосентенціальної форми, що не виходить за правий кінець крайньої справа основи цієї сентенціальної форми. Відповідно до цього визначення, до кінця активного префікса завжди можна додати термінальні символи для одержання правосентенціальної форми. Отже, просканована частина вхідного потоку не містить помилок тільки в тому випадку, коли вона може бути згорнута в активний префікс.

5.2.4 Конфлікти в процесі пз-аналізу

Існують контекстно-вільні граматики, для яких ПЗ-аналіз не можна застосувати. Будь-який ПЗ-аналізатор для такої граматики може досягти конфігурації, у якій синтаксичний аналізатор за інформацією про вміст стека й про черговий вхідний символ не в змозі вирішити, що належить використати: перенос або згортку (конфлікт перенос/згортка, shift/reduce conflict), або яка з декількох можливих згорток повинна застосовуватися (конфлікт згортка/згортка, reduce/reduce conflict). Зараз ми розглянемо кілька прикладів синтаксичних конструкцій, що приводять до побудови таких граматик. Технічно ці граматики не входять до класу LR(k)-граматик, що буде визначено далі; ми говоримо про їх як про не-LR-граматики. k в LR(k) означає кількість символів вхідного потоку, що розташовані за поточним, які синтаксичний аналізатор може при необхідності переглянути, не переносячи в стек. Практично використовувані граматики в основному належать класу LR(1).

Приклад 5.11. Неоднозначна граматика не може бути LR-граматикою. Розглянемо класичний випадок граматики "else, що кочує " (4.7) з п. 4.5.1:

stmt ::= if expr then stmt

| if expr then stmt else stmt

|other

Якщо ПЗ-аналізатор перебуває в конфігурації

Стек Вхід

… if expr then stmt else … $

то ми не можемо сказати, чи є підрядок if expr then stmt основою, незалежно від того, що перебуває в стеку під нею. Тут виникає конфлікт перенос/згортка – залежно від того, що слідує за else у вхідному потоці: вірним рішенням може виявитися згортка if expr then stmt в stmt, а може – перенос else і пошук ще одного stmt для завершення альтернативи if expr then stmt else stmt. Таким чином, ми не можемо сказати, що варто використати в цьому випадку– перенос або згортку, тому виходить, що граматика не є LR(1)-граматикою. Більше того, ніяка неоднозначна граматика не може бути LR(k)-rpaммaтикoй ні при якому k.

Слід зазначити, однак, що ПЗ-аналіз може бути легко адаптований до розбору деяких неоднозначних граматик на зразок наведеної вище. При побудові такого синтаксичного аналізатора для граматики, що містить дві наведені вище продукції, ми одержимо конфлікт переносу/згортки – переносу else або згортки stmtif expr then stmt. Якщо ми розв'яжемо конфлікт на користь переносу, синтаксичний аналізатор буде працювати нормально.

Ще одна причина того, що граматика не є LR-граматикою, виникає, коли є основа, але вмісту стека й чергового вхідного символу недостатньо для визначення продукції, що повинна використатися в згортці. Наступний приклад ілюструє цю ситуацію.

Приклад 5.12. Припустимо, що є лексичний аналізатор, який повертає токен id для всіх ідентифікаторів, незалежно від їхнього використання. Припустимо також, що наша мова викликає процедури по іменах, з параметрами, узятими в дужки; той же синтаксис використається й для роботи з масивами. Оскільки трансляції індексів масиву й параметрів процедури істотно відрізняються друг від друга, ми повинні використати різні продукції для породження списку фактичних параметрів й індексів. Отже, наша граматика може мати (серед інших) продукції типу:

(1)

stmt

::=

id (parametr_list)

(2)

stmt

::=

expr:= expr

(3)

parametr_list

::=

parametr_list, parametr

(4)

parametr_list

::=

parametr

(5)

parametr

::=

id

(6)

expr

::=

id(expr_list)

(7)

expr

::=

id

(8)

expr_list

::=

expr_list, expr

(9)

expr_list

::=

expr

Інструкція, що починається з A(i,j), буде передана синтаксичному аналізатору як потік токенів id(id,id). Після переносу перших трьох токенів у стек ПЗ-аналізатор виявиться в конфігурації

Стек Вхід

… id(id , id) …

Очевидно, що токен id на вершині стека повинен бути згорнутий, але якою продукцією? Правильний вибір – продукція (5), якщо А – процедура, і (7), якщо А – масив. Вміст стека не може підказати, чим є А; для прийняття рішення ми повинні використати інформацію з таблиці символів, що була занесена туди при оголошенні А.

Одне з рішень складається в заміні токена id у продукції (1) на procid і використанні більш інтелектуального лексичного аналізатора, що повертає procid при розпізнаванні ідентифікатора, що представляє собою ім'я процедури. Такий спосіб вимагає від лексичного аналізатора звертання до таблиці символів перед тим, як повернути токен.

Якщо ми внесемо ці зміни, то при обробці A(i,j) синтаксичний аналізатор може виявитися або в конфігурації, наведеної раніше, або в наступній:

Стек Вхід

... procid(id , id )...

У першому випадку вибираємо згортку по продукції (7); в останньому – по продукції (5). Звернимо увагу, що вибір визначається третім від вершини символом у стеку, що навіть не бере участь у згортці. Для керування розбором ПЗ-аналіз може використати інформацію "із глибин" стека.

27

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