Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LoSWS_L_2_4_ВиртПроц_1.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
175.62 Кб
Скачать

Трансляция условных операторов и циклов

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

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

Команды, соответствующие этим операторам, формируются по следующему шаблону (L1 и L2 означают адреса команд):

if С then S

while С do S

команды для условия С

L1: команды для С

JPC L1

JPC L2

команды оператора S

команды для S

L1: ...

JMP L1

L2:..

Генерация кода для оператора условного перехода

if <условие> then < оператор >

STMT = if LOGIC then STMT

STMT = ? LOGIC : STMT вариант с 1-символьным кл.словом

адрес

if LOGIC then STMT

команды для условия LOGIC

op_jmpc; L1

команды оператора STMT

L1:

...

STMT= if LOGIC then { gencode(op_jampc, 0) адреса перехода пока не знаем, запоминаем адрес команды для будущей модификации}

STMT {модифицируем команду, вставляя после нее нужный адрес}

if typeLex=ifsym

then begin

getsym;

LOGIC;

if typeLex=thensym

then getlex

else error(16);

buf:=curr_adr_code; запоминаем адрес

gencode(op_jmpc,0); формируем неполную команду

STMT;

code[buf].adr:= curr_adr_code модифицируем

команду

end

code[ ].op

code[].adr

curr_adr_code указатель на св.адрес

Генерация кода для оператора цикла

While <условие> do < оператор >

STMT= while LOGIC do STMT

STMT= # LOGIC ^ STMT

адрес

while LOGIC do S

L1:

команды для LOGIC

JPMC L2

команды для STMT

JMP L1

L2:

..

if typeLex =whilesym

then begin

buf1:= curr_adr_code;

getsym;

LOGIC;

buf2:= curr_adr_code;

gencode(jpc,0); выход из цикла

if typeLex =dosym

then getsym

else error(18);

STMT;

gencode(jmp,buf1); переход на начало цикла

code[buf2].adr:= curr_adr_code модификация jpc по

адресу L1

end;

Процедура формирования кода для виртуальной машины и ее отображения

Инициализация адреса 1 команды

curr_adr_code=1

Процедура формирования

Void TForm1:: gencode(AnsiString oper, int val);

{ code[curr_adr_code.op=oper; запись кода операции

code[curr_adr_code.adr=val; запись адреса переменной

curr_adr_code++ ; модификация адреса

ListBox_VIEW->Items->Add(oper + “___ “ + IntToStr(val)

Отображение команды

}

Упражнения

Написать код виртуальной машины с реализацией операций в соответствии с заданным вариантом:

Арифм

сравнения

логичес

с адресом

1

- унар

>

~

op_not

op_jamp

2

+

>=

|

op_or

op_jampC

3

-

!>

&

op_and

op_pushC

4

*

<

op_xor

op_pushV

5

/

<=

op_imp

op_popV

6

%

!<

op_equ

7

|x|

abs

=

8

x2

!=

+=

9

sign

<>

-=

10

++

*=

11

--

/=

12

%=

Процедура генерации кода

Языки

Паскаль

С++

С#

Java

Процедура проверки правила

1

PRG

2

DECLARE

3

ELEM

4

BLOCK

5

STMT

6

LOGIC

7

EXPR

8

MULT

Преобразовать процедуру проверки правила в атрибутную процедуру, добавив команды генерации кода

Разработать правила описания логических выражений с операциями:

И или нет импликация тождественности сложения по модулю 2

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]