Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЯП, ТВП / ТЯПМТ / Пособие.doc
Скачиваний:
161
Добавлен:
11.05.2015
Размер:
2.37 Mб
Скачать

9. Генерация кода

9.1. Генерация промежуточного кода.

Как отмечалось ранее, код генерируется при обходе дерева, построенного анализатором. Обычно в современных трансляторах генерация кода осуществляется параллельно с построением дерева, но может осуществляться и как отдельный проход. Генерация кода осуществляется в два этапа:

  1. генерация не зависящего от машины промежуточного кода;

  2. генерация машинного кода для конкретной ЭВМ.

Во многих компиляторах оба эти процесса осуществляются за один проход.

Обычно промежуточный код получается разбиением сложной структуры исходного языка на более удобные для обращения элементы.

Одним из распространенных видов промежуточного кода является четверки. Например, выражение

можно представить как четверки следующим образом:

Здесь целые числа соответствуют идентификаторам, присвоенным компилятором. Четверки можно считать промежуточным кодом высокого уровня. Такой код называют трехадресным кодом (два адреса для операндов и один для результата).

Другой вариант кода – тройки (двухадресный код). Каждая тройка состоит из двух адресов операндов и знака операции.

Выражение

можно представить в виде четверок:

и виде троек:

Если сам операнд является тройкой, то используется ее позиция (регистр) для хранения результата.

Как тройки,так и четверки можно распространить не только на выражения, но и на другие конструкции языка. Например, присвоение

в виде четверки представляется как

,

а в виде тройки – как

.

Не менее популярны в качестве промежуточного кода префиксные и постфиксные нотации. В префиксной нотации каждый знак операции появляется перед своими операндами, а в постфиксной - после. Например, инфиксное выражение в префиксной нотации имеет вид, а в постфиксной -.

Префиксная нотация известна также как польская запись, а постфиксная - как обратная польская запись (запись Лукашевича). Например, выражение

в префиксной форме записывается следующим образом:

,

а в постфиксной так:

.

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

Перегруппировку в результате преобразования вможно осуществить с помощью стека. При этом алгоритм сведется к трем действиям:

  1. напечатать идентификатор, когда он встретится при чтении инфиксного выражения слева направо;

  2. поместить в стек знак операции, когда он встретится;

  3. когда встретится конец выражения (или подвыражения), выдать на печать этот знак операции, который находится в стеке.

Префиксные и постфиксные выражения можно также получать из представления выражения в виде бинарного дерева (рис. 9.1).

Пример:

Рис. 9.1. Бинарное дерево

Чтобы получить представление префиксного выражения дерево обходят сверху в порядке:

  • посещение корня;

  • обход левого поддерева сверху;

  • обход правого поддерева сверху,

что дает .

Для получения постфиксного представления дерево обходят снизу:

  • обход левого поддерева снизу;

  • обход правого поддерева снизу;

  • посещение корня.

В результате имеем: .

Далее все исследования будем проводить в терминах промежуточного языка

тип - команды параметры

Тип команды может быть,например, вызовом стандартного обозначения операции:

.

Здесь II+ - сложение двух целых чиселA, B и C служат во время прогона адресами двух операндов и результата. Для того чтобы в промежуточном коде можно было воспользоваться адресами во время прогона, распределение памяти к этому моменту должно быть уже закончено.

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

Адрес на время прогона соотносится со стеком, и каждый адрес можно представить тройкой вида