- •Лекція №1. Тема 1: Компілятори, інтерпретатори, критерії розробки, основні етапи та їх взаємозв’язок . Основні поняття.
- •Критерії розробки трансляторів:
- •Етапи трансляції:
- •Фази трансляції:
- •Лекція №2. Тема 2 : Лексичний аналізатор та його основні задачі. Основна задача лексичного аналізатора.
- •Макроалгоритм та структури даних лексичного аналізатора.
- •Структура даних для розпізнавання роздільників та знаків операцій.
- •Таблиця зарезервованих слів.
- •Таблиця ідентифікаторів.
- •Таблиця типів.
- •Таблиця типів, враховуючи блоки та процедури.
- •Лекція №3. Тема 3 : Синтаксичний аналіз.
- •Метод рекурсивного спуску.
- •Ll(1)-граматика.
- •Приведення до ll(1)-граматики.
- •Алгоритм перевірки належності граматики до класу ll(1)-граматик.
- •Лекція №4. Синтаксичний розбір за допомогою lr(1)-граматики.
- •Лекція №5. Формування lr-таблиці розбору.
- •Лекція №6. Тема 4 : Аналіз контекстних умов.
- •Аналіз контекстних умов за допомогою програмних граматик.
- •Класифікація програмних граматик:
- •Лекція №7. Граматики Ван Вейнгаарда.
- •Розбір з використанням граматики Ван Вейнгаарда та лінійно-обмеженого автомату.
- •Лекція №8. Тема 5 : Генерація коду. Метод включення дій в граматику.
- •Метод включення дій в граматику.
- •Розбір декларативної частини програми.
- •Лекція №9. Тема 6 : Розподіл пам’яті під час виконання (прогону).
- •Структури даних, які необхідні для генерації коду.
- •Лекція №10.
- •Лекція №11. Генерація коду для циклу for.
- •Генерація коду для циклу while.
- •Генерація коду для нескінченого циклу.
- •Генерація коду для декларативної частини програми.
- •Генерація коду вході в процедуру та виході з неї.
- •Лекція №12. Тема 7: Діагностика та виправлення помилок.
- •Точність діагностики помилок.
- •Виправлення помилок.
- •Діагностика помилок.
- •Лекція №13. Тема 8 : Проектування транслятора. Визначення кількості проходів під час трансляції.
- •Тема 9 : Оптимізація коду.
- •Локальна та глобальна оптимізація коду.
- •Критерії оптимізації.
- •Локальна оптимізація коду.
- •Оптимізація лінійної ділянки.
- •Глобальна оптимізація коду.
- •Тема 10 : Генератори компіляторів.
Генерація коду для нескінченого циклу.
Побудуємо граматику для нескінченого циклу:
Маємо такі включені дії:
I1:
4) мітка Li,N;
i заносимо в СЗО;
i=i+1;
0 заносимо в СЗО;
i заносимо в СЗО;
i=i+1;
I2:
в j виймаємо з СЗО;
звільняємо СЗО;
в k заносимо з СЗО;
4) перейти Lk,N;
4) мітка Lj,N;
I3:
j= значенню СЗО , залишаємо його в СЗО ( після 0);
4) перейти Lj,N.
Генерація коду для декларативної частини програми.
Маємо таку граматику з включеними діями:
Розглянемо включені дії:
K1:
дії лексичного аналізатора:
ідентифікатор заносимо в таблицю ідентифікаторів. При розборі типу необхідно, або
вибрати тип із передбачених типів, або ж добавити новий тип в таблицю типів.
K2:
лексичний аналізатор повинен проставити тип у всіх ідентифікаторів, які не мали типу. В таблицю ідентифікаторів заносимо адресу стеку ідентифікаторів (лише для того ідентифікатора в якого є тип), при цьому адреса збільшується на величину ідентифікатора.
Генерація коду вході в процедуру та виході з неї.
При вході в процедуру:
будується новий запис таблиці блоків;
генеруються коду для завантаження локальної середи посилань та змінюється нелокальна середу посилань. Можуть бути коди для завантаження локальної середи посилань в стек часу прогону та зміна стеку-дисплею, або ж коди для зміни центральної таблиці;
будуються коди для прийняття параметрів.
При виході з процедури:
будуються коди для порівняння параметрів типу результату, значення-результату;
будуються коди для зміни нелокальної середи посилань, тобто зміни стеку-дисплею, або ж відновлення центральної таблиці;
завершується формування запису таблиці блоків.
Лекція №12. Тема 7: Діагностика та виправлення помилок.
Компілятори знаходять помилки по різному: в режимі пошуку до першої помилки; в режимі пошуку всіх помилок.
Під час аналізу всієї програми компіляторові необхідно виправляти помилки, тобто вносити зміни в програму, щоб виявлення інших помилок було правильним. Якість виявлення помилок залежить від:
точності виявлення помилки (наскільки впливає наявність попередньої помилки на виявлення та діагностику даної помилки);
повідомлення в потрібному місці;
повідомлення максимально конкретизоване.
Часто компілятор формує лістинг компіляції, який містить:
текст програми (нумерацію операторів, рівень вложеності процедур і т.п.);
повідомлення про помилку (може бути список помилок);
карту пам’яті для локальної середи посилань (якщо псується яка-небудь інформація, можна прослідкувати де псуються дані);
таблицю перехресних посилань.
Наявність лістингу поліпшує отладку програми, але якщо вона на паперові, але не на екрані.
Точність діагностики помилок.
Можна не якісно відшукати помилки. Причини:
Помилка виявляється не в тому місці де вона допущена, а в тому де вона може бути виявлена, наприклад, кількість відкриваючих та закриваючих дужок.
Навіть, якщо помилка виявлена, не завжди точно конкретизоване повідомлення, а більш того в деяких випадках це повідомлення можна було б інакше сформулювати.
Виправлення помилок.
Існують такі види помилок:
Лексичні помилки:
а) недопустимий символ. Способи виправлення :
Усунення недопустимого символу;
Заміна деяким універсальним символом;
б) нерозпізнана лексема. Шляхи виправлення:
Заміна універсальною лексемою, тобто тим що повинно бути на вході у лексичного аналізатора;
Пошук найбільш близької по напису лексеми;
Спроба розподілу лексеми на дві допустимі лексеми, наприклад,
в) некоректно задані коментарі або ж літерали. Шляхи вирішення проблеми:
Примусове закриття лапок за необхідною кількістю;
Виправлення коментарів до кінця рядка, в інших випадках лексичний аналізатор виправити помилку не в змозі;
г) невірне представлення числа, наприклад, 1.2.3, в цьому випадку замінюється на один літерал.
Для виправлення помилки лексичний аналізатор може користуватися інформацією синтаксичного аналізатора про очікувані лексеми.
Синтаксичні помилки. Розглянемо на прикладі:
Використовуються стратегії:
а) режим переполоху:
Виключаються всі лексеми до деяких очікуваних, для виразу A очікувані будуть then. Необхідно помістити додаткову дію в граматику та в таблицю розбору добавити додаткові дії, наприклад,
R1:
Занесемо в усі стеки спеціальну мітку;
R2:
Очищення стеку, включаючи спеціальну мітку. Необхідно діяти до параметру then і номер стану в таблиці розбору, та опустити лексему в програмі.
б) виключення символів, наприклад, (a+b))*c або a+b,; end:
Виправлення як контекстних умов;
У випадку коли зустрівся недопустимий символ, в таблицю розбору можна включити допоміжну графу – недопустимі символи;
в) включення символів, наприклад,
Відвести графу в таблиці розбору символи включення ;
г) включення помилок в граматику;
д) ремонт на мінімальній відстані:
Спробувати вставити або ж видалити щось, щоб ланцюг став допустимим. Цю дію важко виконати в LL(1)-граматиці так, як це розбір з поверненням.
Найбільш ефективні 1 – 4 стратегії для LL(1)-граматики. В кожнім місці необхідно підібрати стратегію, яка найбільш ефективна для даного випадку.
Контекстно-залежні помилки:
Контекстні умови не передбачають виправлення програми, а припиняється генерація коду. Семантичні помилки, такі як (a/0), (b/(a-a)), (int a[7]; a[9]:=7) не виправляються транслятором. Вони виявляються на етапі виконання об’єктного модуля.
Помилки часу виконання, такі як:
Нестача пам’яті;
Ділення на нуль;
Переповнення порядку;
Вихід індексу за рамки масиву;
Зацикленість.