- •4.Основні частини компілятора.
- •5Лексичний аналіз роботи з таблицями
- •6. Синтаксичний та семантичний аналіз, дерева
- •7. Польський запис, тетради.
- •8. Формальне визначення мови, операції над мовами.
- •9. Граматики
- •11.Регулярний вираз
- •12) Нормальна форма Бекуса-Наура
- •13. Ієрархія Хомського
- •14. Регулярні граматики.
- •15. Скінченні автомати
- •16. Детерміновані і недетерміновані кінцеві автомати.
- •18. Побудова детермінованих кінцевих автоматів за недетермінованими кінцевими автоматами.
- •19. Програмування сканера.
- •20. Таблиці символів, хеш-функції, хеш-адресація
- •21. Колізія, ре хешування
- •23.Контекстно-выльны граматики.
- •24. Синтаксично-керований переклад
- •25. Переклад інфіксної форми запису у польську
- •26. Алгоритм синтаксично-керованого перекладу:
- •27. Автомати з магазинною пам’яттю
- •28. Операторні граматики
- •29.Алгоритм розборуоператорних грамматик.
- •37. Оптимізація булевих виразів, циклів.
- •38. Генерація коду. Скп на мову Асамблер.
- •39. Інтерпретатори, адресація, представлення ідентифікаторів.
- •40 Компілятор компіляторів.
- •41 Генератор лексичних аналізаторів.(lex)
- •42. Генератор синтаксичних аналізаторів.
- •43. Приклади застосування генераторыв.
38. Генерація коду. Скп на мову Асамблер.
Побудуємо алгоритм генерації коду, що на вході отримує дерево оптимізації й створює для цього дерево код для побудови внутрішньої лінійної ділянки результуючої програми. По дереву операцій можна використати найпростішу процедуру вхідного дерева редукції. Процедура має визначати тип вузла дерева, що відповідає типу операції. На базі цього типу будується код вузла. Якщо всі вузли нижчого рівня для поточного вузла є листками, то в код включають операнди, які відповідають листкам, ото отриманий код є результатом виконання процедури, інакше процедура має викликати сама себе для генерації нижче розміщених вузлів дерева й результат включити в свій створений код. Фактично відбувається конкатенація ланцюгів-команд. Таким чином, щоб операція для нижче розміщених вузлів виконувалась до
В дереві можливі 4 випадки, які відповідають типу поточного вузла:
Два листи-операнди.
Тільки лівий нижній вузол є листком-опрандом, а правий є операцією.
Тільки правий лист є операндом.
Два нижче розміщених вузлів(листків) є операціями.
Представлення проміжного коду:
Будемо рахувати, що операнди можуть розміщуватися в 16-розрядних регістрах процесору типу 80х86, при чому позначимо, що реєстр АХ є акумулятором, ДХ – регістр даних, є стек, де зберігаються проміжні дані.
Для того, щоб ми могли будувати проміжний код, введемо функцію Code, яка реалізує перехід вузла дерева. Вхідними є дані про вузол дерева операцій, вихідними – послідовність команд Asembler.
Приведем в таблиці результуючий код для кожного типу вузла.
act
oper1 oper2 |
mov AX, oper1 act AX, oper2 |
act – відповідна операція у вузлі. oper1 i oper2 – операнди. mov – операція пересилки даних із змінної в реєстр.
|
act
oper1 вузол2 |
code (вузол2) mov DX,AX mov AX, oper1 act AX,DX |
вузол2 – не є листком і не є операндом code – позначає той код, що породжуватиметься процедурою для вузла нижчого рівня. |
act
вузол2 oper2 |
code (вузол2) act AX, oper2
|
|
act
вузол2 вузол3 |
code (вузол2) Push AX code (вузол3) mov DX,AX pop AX act AX,DX |
Push – команда збереження Pop – команда витягнення результатів у/з систем. |
Команди:
Додавання – add
Віднімання – sub
Множення – mul
Ділення – div
У командах множення і ділення в якості першого операнду передбачають регістр АХ, який команді можна не вказувати. Крім того, потрібно розглянути випадки для операції присвоєння:
-
:=
oper1 oper2
mov AX, oper2
mov oper1, AX
:=
oper1 вузол2
code (вузол2)
mov oper1, AX
Розглянемо в якості прикладу переклад виразу: А:=В+С+Д-В+10
Розглянемо послідовність побудови проміжного коду за допомогою рекурсії:
code (U2)
mov A, AX
code (U5)
push AX
code (U5)
mov DX, AX
pop AX
sub AX, DX
mov A, AX
code(U4)
add AX, D
push AX
code (U5)
mov DX, AX
pop AX
sub AX, DX
mov A, AX
mov AX, B
mul C
add AX, D
push AX
code (U5)
mov DX, AX
pop AX
sub AX, DX
mov A, AX
mov AX,B
mul C
add AX,D
push AX
mov AX, B
mul 10
mov DX,AX
pop AX
sub AX, DX
mov A, AX
Генерація тріад.
Для перетворення вузлів дерева тріад використовують функцію code, вхідні вихідні дані ті самі. Тріади пов’язані між собою, тому для встановлення взаємозв’язку функції генерації коду повинні враховувати також поточний номер наступної тріади. Вузли ті самі.
act
oper1 oper2 |
|
|
act
oper1 вузол2 |
i)code(вузол2, i) – створє послідовність тріад з і для вузла2 i+j) act(oper1, ^(i+j-1)) |
i+j, і – номер тріади ^ – посилання на тріаду з даним номером J – послідовність тріад, яка створ. для вузла2 |
act
вузол2 oper2 |
i)code(вузол2, i) i+j) act(^(i+j+1), oper2) |
|
act
вузол2 вузол3 |
i)code(вузол2, i) i+j)code(вузол3, i+j)
i+j+k) act(^(i+j-1),^(i+j+k-1), oper2) |
|
Для тріад не потрібно враховувати операцію присвоєння як окремий тип вузла дерева, це звичайна операція виклику для тріади.