Вход/Регистрация
UNIX — универсальная среда программирования
вернуться

Керниган Брайан Уилсон

Шрифт:

Под простой машиной здесь подразумевается стековая машина: когда появляется операнд, он заносится в стек, точнее, создаются команды, заносящие операнд в стек). Большинство операций над операндами выполняется в вершине стека. Например, при обработке присваивания

x=2*y

создаются следующие команды:

constpush
Записать в стек: константа … константа2

2

varpush
Записать указатель на таблицу имен в стек

y
… для переменной у

eval
Вычислить: заменить указатель значением

mul
Перемножить два верхних элемента; результат заменяет их

varpush
Записать указатель на таблицу имен в стек

x
… для переменной x

assign
Записать значение в переменную, убрать указатель

pop
Убрать верхний элемент из стека

STOP
Конец последовательности команд

Когда выполняются команды, выражение вычисляется и результат записывается в

x
, как и указано в примечаниях. Последняя команда
pop
удаляет из стека верхний элемент, поскольку он больше не нужен.

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

Структура таблицы имен для

hoc4
совпадает с таковой для
hoc3
: инициация проводится в
init.c
, и математические функции, находящиеся в
math.c
, одни и те же. Грамматика
hoc4
идентична грамматике
hoc3
, но действия совершенно иные. Вообще, каждое действие порождает машинные команды и все необходимые для них аргументы. Например, в случае появления
VAR
в выражении создаются три команды: команда
varpush
, указатель на таблицу имен для переменной и команда
eval
, которая заменяет при вычислении указатель на таблицу имен соответствующим значением. Код для
'*'
содержит одну команду
mul
, поскольку операнды для нее уже находятся в стеке.

$ cat hoc.y

%{

#include "hoc.h"

#define code2(c1,c2) code(c1); code(c2)

#define code3(c1,c2,c3) code(c1); code(c2); code(c3)

%}

%union {

 Symbol *sym; /* symbol table pointer */

 Inst *inst; /* machine instruction */

}

%token <sym> NUMBER VAR BLTIN UNDEF

%right '='

%left '+'

%left '*' '/'

%left UNARYMINUS

%right '^' /* exponentiation */

%%

list: /* nothing */ | list '\n'

 | list asgn '\n' { code2(pop, STOP); return 1; }

 | list expr '\n' { code2(print, STOP); return 1; }

 | list error '\n' { yyerrok; }

 ;

asgn: VAR '=' expr { code3(varpush, (Inst)$1, assign); }

 ;

expr: NUMBER { code2(constpush, (Inst)$1); }

 | VAR { code3(varpush, (Inst)$1, eval); }

 | asgn

 | BLTIN '(' expr ')' { code2(bltin, (Inst)$1->u.ptr); }

 | '(' expr ')'

 | expr '+' expr { code(add); }

 | expr '-' expr { code(sub); }

 | expr '*' expr { code(mul); }

 | expr '/' expr { code(div); }

 | expr '^' expr { code(power); }

 | '-' expr %prec UNARYMINUS { code (negate); }

 ;

%%

/* end of grammar */

...

Inst
является типом данных машинной команды (указатель на функцию, возвращающую
int
), к обсуждению которого мы вскоре вернемся. Обратите внимание на то, что аргументами для программы
code
служат имена функций, т.е. указатели на функции или другие совместимые с ними величины.

Мы несколько изменили процедуру

main
. Теперь происходит возврат из анализатора после выполнения каждого оператора или выражения, и порожденный код выполняется. При обнаружении файла
yyparse
возвращает нуль.

main(argc, argv) /* hoc4 */

 char *argv[];

{

 int fpecatch;

 progname = argv[0];

 init;

 setjmp(begin);

  • Читать дальше
  • 1
  • ...
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: