Var[1..V_max] - массив переменных
code[1..c_max] – массив команд
№ |
операция |
Мнемокод |
Выполнение |
16 |
Запись константы в стек |
op_pushC константа |
push(curr_code.adr) |
17 |
Запись значения переменной в стек |
op_pushV адр_пер |
push(var[curr_code.adr]) |
18 |
Запись вершины стека по адресу |
op_pop адр_пер |
|
19 |
Безусловный переход по адресу |
op_jamp адр_ком |
curr_adr = adr_com |
20 |
Условный переход по адресу если результат сравнения Истина |
op_jmpC адр_ком |
if pop=1 then curr_adr = adr_com else curr_adr=curr_adr + 1 |
Виртуальная машина в процессе выполнения команд должна обнаруживать и выводить сообщения об ошибках времени выполнения:
несуществующая операция
некорректный адрес перехода
некорректный операнд (деление на ноль)
Алгоритм работы виртуальной машины
Procedure VirtComp(
Code array[1..CMAX) of instr, {целевой код}
Var array[1..VMAX] of integer) {переменные}
begin
curr_adr:=1; {установка начального адр}
curr_code:=code[curr_adr]; {выборка 1 команды}
{команды будут выбираться до команды «СТОП»}
while curr_code.op<>op_stop do
begin
{блок интерпретации команд}
case curr_code.op of
{многоальтернативный оператор выбора}
op_plus: begin push(pop+pop); {сложение}
curr_adr:=curr_adr+1 end;
op_sub: begin buf:=pop; push(pop-buf);
curr_adr:=curr_adr+1 end; {вычитание}
. . . . . . . .
op_less: begin buf:=pop; {сравнение по <}
if pop<buf then push(1)
else push(0) end;
. . . . . . . .
{запись в стек констант и переменных}
op_pushC: begin push(curr_code.adr);
curr_adr:=curr_adr+1 end;
op_pushV: begin push(var[curr_code.adr]]);
curr_adr:=curr_adr+1 end;
{безусловный и условный переход}
op_jamp: curr_adr:=curr_code.adr;
op_jampC: begin if pop=1
then curr_adr:=curr_code.adr]
else curr_adr:=curr_adr+1 end;
else w_err(«некорректный код операции»)
end{case};
curr_code:=code[curr_adr]; {выборка команды}
end {while}
end { VirtComp}
Преобразование грамматики в атрибутную грамматику
(синтаксически управляемый перевод для виртуальной машины)
активные действия: {gencode(код_операции, операнд)}
действия над атрибутами
Правило
MULT
MULT=id | number | ( EXPR )
Добавляем активные действия, атрибуты
MULT= idP {gencode(op_pushV, P)} |
numberP {gencode(op_pushC, P)} |
( EXPR )
ADD
ADD = MULT { oper MULT }
ADD = MULT { operP {R=P запомнить операция} MULT {gencode(R, 0)} }
Аналогично EXPR
Аналогично LOGIC
Оператор присваивания
STMT= id =EXPR
STMT= idP =EXPR {gencode(op_pop, Q)} Q:=P
If typeLex=id then
Begin
Buf=valueLex
Getlex();
EXPR();
Gencode(op_pop, buf)
End
Else if typeLex=view then
Оператор вывода VIEW
STMT= view EXPR
STMT= view EXPR {gencode(op_view, 0)}
if typeLex=view then
begin
getlex();
EXPR();
gencode(op_view, 0)
end
else if typeLex=view then
