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

9.3. Генерация кода для типичных конструкций

9.3.1. Присвоение

destination := source

Значение, соответствующее источнику, присваивается значению, которое является адресом:

р := x + y (значениеx + y присвоить p)

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

Проверяется непротиворечивость типов получателя и источника. Так как получатель представляет собой адрес, источник должен давать что-нибудь приемлемое для присвоения этому адресу. В зависимости от реализуемого языка типы получателяиисточника можно определенным образом менять до выполнения операции присвоения. (Если источник — целое число, то его можно сначала преобразовать в вещественное, а затем присвоить адресу, имеющему тип вещественного числа.)

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

begin pointer real xx

begin real x

xx := x

end

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

Генерируется код присвоения, имеющий форму

ASSIGN type, S, D,

где S — адрес источника,D — адрес получателя.

Если язык ориентирован на выражения (то есть само присвоение имеет значение), статические характеристики этого значения помещаются в нижний стек.

9.3.2. Условные зависимости

If b then c else d

При генерации кода для такой условной зависимости во время компиляции выполняются три действия. Грамматика с включенными действиями имеет вид:

CONDITIONAL if B<A1> then C<A2> else D<A3>

Действия А1, А2, А3(next — значение номера следующей метки, присваиваемое компилятором) означают:

А1. Проверить типВ, применяя любые необходимые преобразования типа для получения логического значения. Выдать код для перехода кL<next>, еслиВесть «ложь»:

JUMPF L<next>, <address of B>

Поместить в стек значение next(обычно для этого используется стек знаков операций). Увеличитьnext на 1. (Угловые скобки используются для обозначения значений величин, заключенных в них).

А2. Генерировать код для перехода через ветвьelse(то есть переход к концу условной зависимости):

GO TO L<next>.

Удалить из стека номер метки (помещенный в стек действием А1), назвать ееi, генерировать код для размещения метки:

SET LABEL L<i>.

Поместить в стек значение next. Увеличитьnextна 1.

А3. Удалить из стека номер метки (j). Генерировать код для размещения метки:

SET LABEL L<j>.

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

Аналогично можно обращаться с вложенными условными выражениями.

9.3.3. Описание идентификаторов

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

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

Текущее значение указателя стека идентификаторов дает адрес, который нужно выделить под х. Этот адрес

(idstack, current block number, instack pointer)

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

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