Теория языков программирования и методы трансляции Тема 8 Генерация кода.

Презентация:



Advertisements
Похожие презентации
Лекция 4 Программирование на Паскале. Элементы языка Турбо Паскаль 7.0. Типы данных. Управляющие конструкции.
Advertisements

Глава 6. УПРАВЛЯЮЩИЕ СТРУКТУРЫ Оператор присваивания Простой и составной операторы Условный оператор Оператор множественного выбора Оператор цикла с предусловием.
Внутреннее представление компилятора Типы представлений и их особенности.
М.Ю. Харламов, ВНУ им. В.Даля, Генерация объектного кода это перевод компилятором внутреннего представ­ления исходной программы в цепочку символов.
Теория компиляторов-1. Л.51 Классическая теория компиляторов Лекция 5.
М.Ю. Харламов, ВНУ им. В.Даля, Семантический анализатор Семантический анализатор выполняет следующие основные действия: проверку соблюдения во входной.
ЛАБОРАТОРНАЯ РАБОТА 1 ПРОЕКТИРОВАНИЕ И РЕАЛИЗАЦИЯ ТАБЛИЦ, ИСПОЛЬЗУЕМЫХ В ТРАНСЛЯТОРЕ Рейн Т. С.
Министерство образования Республики Беларусь Белорусский государственный университет Управляющие структуры языков программирования.
Семантический анализ КC-грамматики, с помощью которых описывают синтаксис языков программирования, не позволяют задавать контекстные условия (КУ), имеющиеся.
Введение в программирование. Компоненты системы программирования Среда Режимы работы Система команд Данные Язык программирования Среда программирования.
Объектно-ориентированное программирование Карпов В.Э. Смолток. Лекция 4. Байт-код.
Языки и методы программирования Преподаватель – доцент каф. ИТиМПИ Кузнецова Е.М. Лекция 3.
Лекция 4 Представление основных структур: итерации, ветвления, повторения. Вспомогательные алгоритмы и процедуры.
Машинная команда Энциклопедия учителя информатики Газета «Первое сентября»
Язык высокого уровня компилятор Программа компиляторов Сделал:Студент группы:Ис-2о(очная)Воротов Валентин.
Лекция 7 Управление памятью Сегментная, страничная и сегментно- страничная организация памяти.
Часть II. Формальное описание языков программирования ( Формальная спецификация формальных языков ) Атрибутные грамматики (2). Генерация кода.
Язык программирования Delphi. Алфавит языка 53 буквы латинского алфавита и символ подчеркивания Цифры от 0 до 9 23 спец.символа
Лекция 7. Структура языка С/С++. Операторы ветвления: условный оператор if. Полное ветвление. Неполное ветвление. Оператор множественного выбора switch.
Тема 2. Операторы (инструкции) передачи управления. Условный оператор (инструкция) и его формы. Логические выражения и логические переменные. Составные.
Транксрипт:

Теория языков программирования и методы трансляции Тема 8 Генерация кода

Вопросы В этой теме будет рассмотрена фаза генерации кода при компиляции. В частности, будут рассмотрены следующие вопросы. Различные типы промежуточного кода, создаваемого компилятором, и то, как они генерируются. Оптимизации кода и ее осуществление в различных фазах процесса компиляции. Некоторые моменты, связанные с генераторами генераторов кода. В то же время вместо всестороннего рассмотрения всех аспектов генерации кода основное внимание будет уделено вопросу создания кода. Детальное рассмотрение того, как может выполняться код, созданный для какой-то конкретной машины, скорее запутает, чем прояснит ситуацию.

Создание промежуточного кода Существует ряд причин для создания компиляторами промежуточного кода как первого шага к созданию кода для реальных машин. Перечислим эти причины. Обеспечение четкого разделения меду машинно-независимой и машинно-зависимой частями компилятора. Минимизация усилий для переноса компилятора в новую среду. Минимизация усилий для реализации m языков на n машинах. Простота оптимизации. Промежуточный код может выглядеть по-разному. Он может связываться с реализуемым языком, например Р-код для языка Pascal, байт- код для языка Java. В качестве альтернативы он может также связываться с машинами, на которых осуществляется реализация.

Создание промежуточного кода Промежуточный язык может быть близким к реализуемым языкам или к машинам, на которых осуществляется реализация. В любом случае он представляет собой линеаризацию синтаксического дерева, созданного в процессе синтаксического и семантического анализа, и формируется посредством разбиения древовидной структуры на последовательность инструкций, каждая из которых эквивалентна одной или нескольким машинным командам. Машинный код может генерироваться, исходя только из промежуточного кода, хотя при этом может потребоваться доступ к таблице символов или другая информация, относящаяся к процессу компиляции.

Создание промежуточного кода Существует три наиболее известных промежуточных кода. 1. Трехадресный код. 2. Р-код – ориентированный на конкретный язык промежуточный код, на котором основано большинство реализаций Pascal. 3. Байт-код, используемый Java Virtual Machine.

Трехадресный код Примером трехадресного кода (three-address code) является строка a = b op c Здесь op – арифметический (или другой) оператор, b и c – его операнды (или их адреса), a – адрес результата применения оператора к операндам. Арифметическое выражение (а + b)*(с + d) можно представить в виде последовательности таких инструкций трехад­ ресного кода t 1 = a + b t 2 = c + a t 3 = t 1 * t 2 Здесь t – создаваемые компилятором временные имена. Можно также применять унарные операторы. Например, оператор -m создаст инструкцию t 1 = -m (хотя, безусловно, в этом случае трехадресный код будет содержать всего лишь два адреса!)

Трехадресный код Преобразование выражений в последовательность инструкций трехадресного кода легко осуществляется с помощью анализатора на основе YACC, подобного использованному при создании постфиксной записи. Грамматика YACC с действиями выглядит следующим образом. S : EXP; EXP : TERM | EXP + {A1();} TERM {A2();} | EXP – {A1();} TERM {A2();}; TERM : FACT | TERM* {A1();} FACT {A2();} | TERM/ {A1();} FACT {A2();}; FACT : – {A1();} FACT {A4();} | VAR {A3();} | ( EXP ); VAR : a | b | c | d | e;

Трехадресный код Необходимо, чтобы многоцелевой стек мог хранить операторы и операнды. Действиями являются: A1 – занести оператор в стек; A2 – следующим образом напечатать инструкции трехадресного кода: напечатать имя следующей распределяемой временной величины напечатать "=" напечатать три верхних элемента стека снизу вверх занести в стек только что распределенное имя временной величины; A3 – занести в стек операнд; A4 – следующим образом напечатать инструкции трехадресного кода: напечатать имя следующей распределяемой временной величины напечатать "=" напечатать два верхних элемента стека снизу вверх занести в стек только что распределенное имя временной величины.

Трехадресный код Трехадресный код может также применяться для представления других аспектов типичных языков программирования, например, присваиваний, обращений к массивам, условных и безусловных переходов. Все следующие выражения являются примерами трехадресного кода. a := t j t i = c[i] goto L if t i goto L Каждый оператор трехадресного кода имеет максимум три адреса, также существуют формы инструкций для присваивания, включающего адреса и указатели, вызовы процедур, вычисление параметров и т.д. Высокоуровневые управляющие структуры, такие как циклы, условные операторы и операторы выбора для создания трехадресного кода, сводятся к проверкам условий и переходам.

Трехадресный код Приведем примеры того, как управляющие структуры компилируются в трехадресный код if (выражение) оператор 1 else олвратор 2 Приведенный выше оператор if можно реализовать путем добавления к грамматике следующих действий. if (выражение) оператор 1 else оператор 2

Трехадресный код Здесь действиями являются : l1 увеличить номер метки образовать код для перехода к метке, если выражение ложно поместить номер метки в стек l2 увеличить номер метки образовать код для перехода к метке извлечь из стека метку, допустим, Lk установить Lk в коде поместить в стек метку, которая выше применялась в безусловном переходе l3 извлечь из стека метку, скажем, L j установить Lj в коде При использовании данной грамматики будет создан следующий код.

Трехадресный код код для вычисления выражения t 1 = not выражение if t 1 goto L 1 код для оператора 1 goto L 2 L 1 код для оператора 2 L 2

Трехадресный код while (выражение) оператор Приведенный выше оператор while можно реализовать путем добавления к грамматике следующих действий. while (выражение) оператор Здесь действиями являются: W1 увеличить номер метки установить метку в коде поместить метку в стек W2 увеличить номер метки образовать код для перехода к метке, если выражение ложно поместить метку в стек W3 извлечь из стека метку, скажем, L j извлечь из стека метку, скажем, L k образовать код для безусловного перехода к L k установить L j в коде

Трехадресный код В результате будет создан следующий код: L 1 : код для вычисления выражения t 1 = not выражение if t 1 goto L 2 код для оператора goto L 1 L 2 : Процесс назначения меток нетривиален и требует использования стека времени компиляции. Он включает в себя переходы вперед и назад по коду, а применимое и определяющее вхождения меток обычно вкладываются "обычным образом". В то же время следует быть осторожными в тех случаях (например, внутри действия W3 ), когда порядок появления меток в стеке не совсем соответствует порядку, в котором они требуются. Стек меток может быть отдельным стеком времени компиляции или может объединяться с другими стеками времени компиляции.