Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

spz / lect / lekc4_4_gener_kodu

.pdf
Скачиваний:
19
Добавлен:
23.02.2016
Размер:
141.41 Кб
Скачать

Генерація коду. Методи генерації коду

1.Загальні принципи генерації коду.

2.Синтаксично керований переклад

Генерація об'єктного коду — це переклад компілятором внутрішнього представлення вхідної програми в ланцюжок символів вихідної мови. Генерація об'єктного коду породжує результуючу об'єктну програму мовою асемблера чи безпосередньо машинною мовою (у машинних кодах). Внутрішнє представлення програми може мати будь-як структуру в залежності від реалізації компілятора, у той час як результуюча програма завжди являє собою лінійну послідовність команд. Тому генерація об'єктного коду (об'єктної програми) у будь-якому випадку повинна виконувати дії, зв'язані з перетворенням складних синтаксичних структур у лінійні ланцюжки.

Генерацію коду можна вважати функцією, визначеною на синтаксичному дереві і на інформації, що міститься в таблиці ідентифікаторів. Тому генерація об'єктного коду виконується після того, як виконаний синтаксичний аналіз програми і всі необхідні дії по підготовці до генерації коду: розподілений адресний простір під функції і змінні, перевірено відповідність імен і типів змінних, констант і функцій у синтаксичних конструкціях вхідної програми і т.д. Характер відображення вхідної програми в послідовність команд, виконуваного генерацією, залежить від вхідної мови, архітектури обчислювальної системи, на яку орієнтована результуюча програма, а також від якості бажаного об'єктного коду.

В ідеалі компілятор повинний виконати синтаксичний розбір усієї вхідної програми, потім провести її семантичний аналіз, після чого приступити до підготовки генерації і безпосередньо генерації коду. Однак така схема роботи компілятора практично майже ніколи не застосовується. Справа в тому, що в загальному випадку жоден семантичний аналізатор і жоден компілятор не здатні проаналізувати й оцінити зміст усієї вхідної програми в цілому. Формальні методи аналізу семантики застосовні тільки до дуже незначної частини можливих вхідних програм. Тому в компілятора немає практичної можливості породжувати еквівалентну вихідну програму на основі усієї вхідної програми.

Як правило, компілятор виконує генерацію результуючого коду поетапно, на основі закінчених синтаксичних конструкцій вхідної програми. Компілятор виділяє закінчену синтаксичну конструкцію з тексту вхідної програми, породжує для неї фрагмент результуючого коду і поміщає його в текст вихідної програми. Потім він переходить до наступного синтаксичній конструкції. Так продовжується доти, поки не буде розібрана уся вхідна програма. У якості аналізованих закінчених синтаксичних конструкцій

виступають оператори, блоки операторів, опису процедур і функції. Їхній конкретний склад залежить від вхідної мови і реалізації компілятора.

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

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

СК-переклад - це основний метод породження коду результуючої програми на підставі результатів синтаксичного розбору. Для зручності розуміння суті методу можна вважати, що результат синтаксичного розбору представлений у виді дерева синтаксичного розбору (або ж дерева операцій), хоча в реальних компіляторах це не завжди так.

Суть принципу СК-перекладу полягає в наступному: з кожною вершиною дерева синтаксичного розбору N зв'язується ланцюжок деякого проміжного коду C(N). Код для вершини N будується шляхом зчеплення (конкатенації) у фіксованому порядку послідовності коду C(N) і послідовностей кодів, зв'язаних із усіма вершинами, що є прямими нащадками N. У свою чергу, для побудови послідовностей коду прямих нащадків вершини N буде потрібно знайти послідовності коду для їхніх нащадків , тобто нащадків другого рівня вершини N — і т.д. Процес перекладу йде, таким чином, знизу нагору в строго встановленому порядку, обумовленому структурою дерева.

Для того щоб побудувати СК-переклад по заданому дереву синтаксичного розбору, необхідно знайти послідовність коду для кореня дерева. Тому для кожної вершини дерева породжуваний ланцюжок коду треба вибирати таким чином, щоб код, приписуваний кореню дерева, виявився шуканим кодом для всього оператора, представленого цим деревом. У загальному випадку необхідно мати однакову інтерпретацію коду C(N), яка б зустрічалася у всіх ситуаціях, де є присутнім вершина N. У принципі ця задача може виявитися нетривіальною, тому що вимагає оцінки змісту (семантики) кожної вершини дерева. При застосуванні СК-перекладу задача інтерпретації коду для кожної вершини дерева вирішується тільки розроблювачем компілятора.

Можлива модель компілятора, у якій синтаксичний аналіз вхідної

програми і генерація коду результуючої програми об'єднані в одну фазу Таку модель можна представити у виді компілятора, у якого операції генерації коду сполучені з операціями виконання синтаксичного розбору. Для опису компіляторів такого типу часто використовується термін «СК-компіляція» (синтаксично керована компіляція).

Схему СК-компіляції можна реалізувати не для усякої вхідної мови програмування. Якщо принцип СКперекладу застосовуваний до усіх вхідних КЗ-мовам, то застосувати СК-компіляцію виявляється не завжди

можливим. Однак відомо, що схеми перекладу на основі СК-компіляції можна побудувати для багатьох із широко розповсюджених класів КЗ-мов, зокрема для LR- і LL-мов.

У процесі СК-перекладу і СК-компіляції не тільки виробляються ланцюжки тексту вихідної мови, але і відбуваються деякі додаткові дії, виконувані самим компілятором. У загальному випадку схеми СК-перекладу можуть передбачати виконання наступних дій:

1.Розміщення у вихідний потік даних машинних кодів або команд асемблера, що представляють собою результат роботи (вихід) компілятора;

2.видача користувачу повідомлень про виявлені помилки і попередження (які повинні бути розміщенні у вихідному потоку, відмінного від потоку, використовуваного для команд результуючої програми);

3.породження і виконання команд, що вказують, що деякі дії повинні бути зроблені самим компілятором (наприклад, операції виконувані над даними, розміщеними в таблиці ідентифікаторів)

Нижче розглянуті основні технічні питання, що дозволяють реалізувати схеми СК-перекладу і СК-компіляції. Але перш ніж розглядати необхідно розібратися зі способами внутрішнього представлення програми в компіляторі. Від того, як вхідна програма представляється усередині компілятора, багато в чому залежать методи, використовувані для обробки команд цієї програми.

Соседние файлы в папке lect