Лекция: Трансляция фрагмента программы

Рассмотрим пример трансляции фрагмента программы «Коды символов».

На рис. 2 показана таблица имен при трансляции описания функции kod, а на рис. 3 — кадр стека функции kod.

 

kod(x,baza)

{ int y;

if ((y = x/baza) != 0)

kod (y,baza);

putchar (x%baza + 48);

}

intc;

main ()

{ c=0;

while (c!=13)

{ c = getchar ();

putchar (61); Рис.2. Таблица имен при

kod (c,10); трансляции функции kod

putchar (61); kod (c,8);

}

}

Трансляция этой программы происходит следующим образом.

 

Для трансляции описания функции kod программа main вызывает подпрограмму oprfun, которая заносит в таблицу имя функции kod, ee формальные параметры х, baza и локальную переменную y и определяет их смещения в кадре стека. После этого Рис.3. Кадр стека функции kod

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

На рис. 4 приведена трассировочная таблица трансляции оператора

if ((y = x / baza) != 0) kod (y,baza);.

При трансляции этого оператора вызванная из oprfun подпрограмма poslop вызывает подпрограмму operatr для трансляции оператора if.

В свою очередь, operatr вызывает подпрограмму virag для трансляции выражения-условия, а затем (рекурсивно) вызывает подпрограмму operatr, которая вызывает virag для трансляции вложенного оператора-выражения.

Программа virag транслирует выражение по секциям. Обработка секции состоит из трех шагов.

1. Если предыдущий ограничитель не является закрывающей скобкой, то читается терм и записывается в стек (для этого в стек вталкивается новый элемент). Дело в том, что после закрывающей скобки секция никогда не содержит терма. Роль терма для нее играет уже находящаяся в стеке информация о значении заключенного в скобки подвыражения.

2. Читается ограничитель секции. Если он не является открывающей скобкой, то его приоритет сравнивается с приоритетом последнего ограничителя, помещенного в стек (если в стеке есть ограничители). Пока приоритет текущего ограничителя меньше приоритета последнего ограничителя стека,

 

leksema = if ogr = prior = ( ( ( ( y = = x / / baza ) )      
st, sz, sogr, spr= 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0
    0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0 0,, (, 0
      3,4,=,2 3,4,=,2 3,4,=,2 3,4,=,2  
        3,2, /,6 3,2, /,6    
          3,3      

 

 

Объектный код, генерируемый приMOV BX,4[BP]

выталкивании операции из стека:MOV AX,6[BP]

CWD POP AX

IDIV BX MOV -2[BP],AX

PUSH AX PUSH AX

Продолжение таблицы вправо:

 

!= != 0 ) )       kod ( ( y,, baza ) )   ;;
0,, (, 0 0,, (, 0 0,, (, 0   3,1,(,0 3,1,(,0 3,1,(,0  
4, ,!=,3 4, ,!=,3       3,4 3,3    
  1,0                

 

 

MOV AX,-2[BP] CC_2:

MOV BX,0 POP AX PUSH AX

POP AX TEST AX,AX

CMP AX,BX JNZ CC_3 MOV AX,4[BP]

MOV AX,1 JMP CC_2 PUSH AX

JNE CC_1 CC_3: CALL KOD

SUB AX,AX

CC_1:

PUSH AX

 

Примечание: В отличие от пособия [1], содержимое стека показано

подробно: в числовом виде.

Рис.4. Трассировочная таблица трансляции оператора

if ((y = x / baza) != 0) kod (y,baza);


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

3. Если ограничитель не является закрывающей скобкой, то по окончании цикла выталкивания он записывается в последний элемент стека (новый элемент не создается). Для ускорения работы туда же помещается его приоритет. Закрывающая скобка в стек не записывается. Вместо этого из стека выталкивается соответствующая открывающая скобка. При выталкивании открывающей скобки подвыражения (перед которой терм отсутствует) терм из вершины стека (информация о значении подвыражения) продвигается на один элемент вглубь стека. Если же открывающая скобка находится перед списком параметров вызова функции (ее термом является имя функции), то при ее выталкивании в выходной файл выводится команда вызова этой функции CALL. Если функция имеет параметр-выражение, то к этому моменту в выходную программу уже будет помещен объектный код этого выражения, т. е. команды, вычисляющие значение параметра и вталкивающие его в стек. В этом случае последний терм стека имеет тип 4 (число, помещенное в стек выполнения). В противном случае параметр не содержит операций (представляет собой константу или переменную). Тогда генерируются команды, помещающие его значение в стек. Запятая разделяет параметры вызова функции и служит как бы закрывающей скобкой предыдущего параметра и открывающей скобкой следующего за ней параметра. Поэтому она обрабатывается подобно закрывающей скобке, но открывающая скобка не выталкивается, а остается в стеке. Таким же образом обрабатывается точка с запятой.

еще рефераты
Еще работы по информатике