|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Метод рекурсивного спуску програмування синтаксичних аналізаторівОзначення. Синтаксична діаграма — це орієнтований граф, дуги котрого позначені елементами Оскільки вершини такого графа не іменуються, то вони припускаються неявно. Синтаксична діаграма позначається іменем нетермінала, для якого вона будується. Мета побудови синтаксичних діаграм для мови програмування на основі КС-граматики: - для кожного А -правила КС-граматики будується синтаксична діаграма; - на основі побудови синтаксичної діаграми для деякого нетермінала Оскільки у більшості випадків при визначенні синтаксису мови програмування ми користуємося множиною рекурсивних правил, то серед підпрограм, які будуються на основі правил граматики, будуть і рекурсивні процедури (рекурсія буде як явна, так і неявна). Сформулюємо правила побудови синтаксичного графа: П1. Кожен нетермінал з відповідною множиною породжуючих правил П2. Для кожного елемента ланцюжка - якщо
Мал.1. - якщо
Мал.2. Тоді, коли правило граматики
Коли правило граматики
….. …… ……
Мал. 3. де замість Якщо на основі граматики мови програмування побудована множина синтаксичних графів, то можна спробувати зменшити їх кількість, скориставшись підстановкою одних графів у інші. При цьому замість елемента - для кожного правила - для фрагмента синтаксичної діаграми виду
Мал.4. відповідний фрагмент програми (наприклад, мовою С) матиме вигляд: extern int lexema_code;// код лексеми, яку виділив сканер extern char lexema_text[ ];// текст лексеми … if (lexema_code==code_x) get_lexema(); else error();
- для фрагмента синтаксичної діаграми виду
Мал.5. відповідний фрагмент програми матиме вигляд: //виклик функції, яка побудована для синтаксичної діаграми f_Ai(); // побудованої для нетермінала
- Для послідовності елементів синтаксичної діаграми виду
Мал.6. відповідний фрагмент програми матиме вигляд: extern int lexema_code; extern char lexema_text[ ]; … {if (lexema_code==code_x1) get_lexema(); else error(); f_A1(); … if (lexema_code==code_xn) get_lexema(); else error(); } Для фрагменту синтаксичної діаграми, побудованої для А-правила, яка має вигляд:
….. …… ……
Мал.7. для кожного - - … - Нехай ми знайшли відповідні множини для кожного - - … - Оскільки за умовою extern int lexema_code; extern char lexema_text[ ]; …. …. void Ai (void) {switch(lexema_code) {case code_ case code_ … case code_ … break; case code_ case code_ … case code_ … break; … …. …. case code_ case code_ … case code_ … break; default: error(); } }//кінець функції для нетермінала
Відмітимо, що до того, як зменшувати кількість синтаксичних діаграм шляхом суперпозиції одних діаграм в інші, необхідно знайти контексти виду Досить часто при визначенні синтаксису мови програмування користуються синтаксичними правилами виду
Мал. 8. Для вище наведеної синтаксичної діаграми відповідні множини будуть: - - Відповідний фрагмент програми мовою С матиме вигляд: extern int lexema_code; extern char lexema_text[ ]; void Ai(void) { while (lexema_code= =code_ lexema_code= =code_ … lexema_code= =code_ {// фрагмент програми для ланцюжка … } }// кінець підпрограми для нетермінала Виконавши аналіз варіантів побудови синтаксичного аналізатора на основі синтаксичних діаграм, покажемо вигляд основної — main-програми: int lexema_code; char lexema_text [500]; int main () { get_lexema (); Axioma_S ();//процедура, пов'язана з аксіомою граматики } 3.6. Побудова LL(k)-синтаксичного аналізатора (k>1). Повернемось до умови, при якій граматика G буде LL(k)-граматикою, а саме: для довільного виводу: Оскільки Означення. Множина Алгоритм. Пошук множини П0: в інших випадках - невизначено. П1: в інших випадках - невизначено. …. ….. …… Пn: в інших випадках - невизначено. …. …. …. Пm: Тоді Виходячи з означення Як наслідок, з алгоритму пошуку Для побудови синтаксичного аналізатора для LL(k)- граматики (k>1) необхідно побудувати множину таблиць, що забезпечать нам безтупиковий аналіз вхідного ланцюжка w (програми) за час пропорційний О(n), де n=| w |. Побудову множини таблиць для управління LL(k)- аналізатором почнемо з таблиці, яка визначає перший крок безпосереднього виводу w в граматиці G: Неформально, коли в магазині автомата знаходиться аксіома S, то нас цікавить перших k термінальних символів, які можна вивести з S (аксіома - поняття "програма") при умові, що після неї (програми) буде досягнуто EOF. Імена інших таблиць Т1, Т2, … Тp визначаються так: Наступні таблиці визначаються так: Наступні таблиці Виходячи з вищенаведеної побудови множини таблиць управління LL(k)- синтаксичним аналізатором видно, що для нетермінала Аi множина таблиць буде наступна: Приклад. Побудувати множину таблиць управління для LL(2)-граматики з наступною схемою правил: Для вищенаведеної граматики множини
а множини Побудуємо першу таблицю Таблиця T0 визначається так:
Нова таблиця управління
Нова таблиця управління
Наступна таблиця
Нова таблиця Ми визначили чотири таблиці-рядки (а їх кількість для довільної LL(k)- граматики визначається так: Об'єднаємо рядки-таблиці в єдину таблицю та виконаємо перейменування рядків:
Алгоритм. Синтаксичний аналізатор для LL(k) -граматики (k>1). П0: Прочитати k лексем з вхідного файла програми (звичайно, інколи менше ніж k). В магазин занести таблицю Т0. …. …. Пi: - Якщо на вершині магазина знаходиться таблиця Ti, то елемент таблиці М(Тi, <k-вхідних лексем>) визначає ланцюжок, який Ti заміщає на вершині магазина. - Якщо на вершині магазина - Якщо досягли кінця вхідного файла програми та магазин порожній, то програма не має синтаксичних помилок. - В інших випадках - синтаксична помилка.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.032 сек.) |