Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Теория языков программирования и методы трансляции..pdf
Скачиваний:
28
Добавлен:
05.02.2023
Размер:
3.41 Mб
Скачать

220

8 ГЕНЕРАЦИЯ КОДА

8.1 ГЕНЕРАЦИЯ ПРОМЕЖУТОЧНОГО КОДА

Как отмечалось ранее, код генерируется при обходе дерева, построен-

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

икак отдельный проход. Генерация кода осуществляется в два этапа [2]:

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

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

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

проход.

Обычно промежуточный код получается разбиением сложной структу-

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

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

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Например, выражение

(–a + b)(с + d)

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

a = 1 1 + b = 2 c + d = 3 2 3 = 4

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

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

221

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

стоит из двух адресов операндов и знака операции [5].

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Выражение

a + b + c d

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

a + b = 1 c d = 2 1 + 2 = 3

и в виде троек:

a + b c d

1 + 2

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

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

гистр) для хранения результата.

Как тройки, так и четверки можно распространить не только на выра-

жения, но и на другие конструкции языка.

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Например, присвоение

a := b

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

a := b = 1,

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

a := b.

222

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Не менее популярны в качестве промежуточного кода префиксные и постфиксные нотации [4]. Например, инфиксное выражение a + b в пре-

фиксной нотации имеет вид + a b, а в постфиксной – a b +.

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Таким образом, в префиксной нотации каждый знак опе-

рации появляется перед своими операндами, а в постфиксной нотации – после. Префиксная нотация известна также как

польская запись, а постфиксная – как обратная польская за-

пись (запись Лукашевича).

·· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Впрефиксной и постфиксной нотациях скобки уже не употребляются,

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

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Например, выражение

(a + b)(c + d)

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

+ a b + c d,

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

a b + c d + .

· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Преобразование привычной инфиксной записи выражений в постфикс-

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

ся к трем действиям:

223

1)напечатать идентификатор, когда он встретится при чтении инфикс-

ного выражения слева направо;

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

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

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

· · · · · · · · · · · · · · · · · · · · · · · ·

 

Пример · · · · · · · · · · · · · · · · · · · · · · ·

 

 

 

Рассмотрим бинарное дерево выражения (a + b) c + d (рис. 8.1).

+

d

+

c

a b

Рисунок 8.1 – Бинарное дерево

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

дят сверху в порядке:

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

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

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

что дает + + a b c d.

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

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

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

посещение корня,

224

врезультате чего имеем a b + c d +.

·· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

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

языка

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

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

ния операции:

STANDOP II+, A, B, C.

Здесь II+ – сложение двух целых чисел, A, B и C служат во время про-

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

ном коде можно было воспользоваться адресами во время прогона, распреде-

ление памяти к этому моменту должно быть уже закончено.

Промежуточный код напоминает префиксную нотацию в том смысле,

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

ями. При получении промежуточного кода для хранения адресов операндов до тех пор, пока не будет напечатан знак операции, используется стек. По-

скольку знак операции можно установить лишь после того, как будут извест-

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

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

(<тип адреса>, <номер блока>, <смещение>).

Тип адреса может быть прямым или косвенным (т.е. содержать значе-

ние или указывать на значение) и ссылаться на рабочий стек или стек иден-

тификаторов. Номер блока позволяет найти номер уровня блока в таблице,

что обеспечивает доступ к конкретной рамке блока через дисплей. Смещение

показывает смещение конкретной рамки по отношению к началу стека.