UNIX — универсальная среда программирования
Шрифт:
%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);
signal(SIGFPE, fpecatch);
for (initcode; yyparse; initcode)
execute(prog);
return 0;
}
Лексический анализатор отличается мало в основном тем, что числа следует сохранять, а не использовать немедленно. Для этого достаточно занести их в таблицу имен вместе с переменными. Ниже приведена измененная часть
yylex
:
yylex /* hoc4 */
...
if (с == '.' || isdigit(c)) {
/* number */
double d;
ungetc(c, stdin);
scanf("%lf", &d);
yylval.sym = install("", NUMBER, d);
return NUMBER;
}
...
Каждый элемент стека интерпретатора является вещественным значением или указателем на запись в таблице имен; тип данных стека объединение всех элементов. Сама машина реализуется как массив указателей на процедуры, выполняющие операции типа
mul
, или на данные в таблице имен. Файл макроопределений hoc.h
увеличивается, поскольку он должен включить эти структуры данных и описания функций для интерпретатора, чтобы они были доступны программе в целом. (Кстати, мы предпочли поместить всю информацию в один файл, а не в два, хотя для больших программ ее целесообразно разделить на несколько файлов с тем, чтобы включать каждый из них только там, где он действительно нужен.)
$ cat hoc.h
typedef struct Symbol { /* symbol table entry */
char *name;
short type; /* VAR, BLTIN, UNDEF */
union {
double val; /* if VAR */
double (*ptr); /* if BLTIN */
} u;
struct Symbol *next; /* to link to another */
} Symbol;
Symbol *install, *lookup;
typedef union Datum { /* interpreter stack type */
double val;
Symbol *sym;
} Datum;
extern Datum pop;
typedef int (*Inst); /* machine instruction */
#define STOP (Inst) 0
extern Inst prog[];
extern eval, add, sub, mul, div, negate, power;
extern assign, bltin, varpush, constpush, print;
$
Процедуры, выполняющие машинные команды и управляющие стеком, хранятся в файле с именем
code.c
. Поскольку содержимое файла составляет около 150 строк, мы покажем его по частям:
$ cat code.c
#include "hoc.h"
#include "y.tab.h"
#define NSTACK 256
static Datum stack[NSTACK]; /* the stack */
static Datum *stackp; /* next free spot on stack */
#define NPROG 2000
Inst prog[NPROG]; /* the machine */
Inst *progp; /* next free spot for code generation */
Inst *pc; /* program counter during execution */
initcode /* initialize for code generation */
{
stackp = stack;
progp = prog;
}
...
Управление стеком осуществляется путем обращений к двум процедурам
push
и pop
:
Поделиться:
Популярные книги
Королевский крест
10. Тайный Город
Фантастика:
боевая фантастика
9.09
рейтинг книги
Статьи из "Арабесок"
Другие редакции
Документальная литература:
публицистика
4.75
рейтинг книги
Газлайтер. Том 5
5. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Политолог
Проза:
современная проза
5.20
рейтинг книги
Имя нам Легион. Том 9
9. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Симфония теней
3. Хроники геноцида
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Я Гордый Часть 3
3. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гражданское право
Научно-образовательная:
прочая научная литература
юриспруденция
6.60
рейтинг книги
Инженер Петра Великого
1. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Тепличный цветок
2. Сестры Кэллоуэй
Любовные романы:
современные любовные романы
7.57
рейтинг книги
Кодекс Охотника. Книга XII
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Дракон
5. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.31
рейтинг книги
Барон не играет по правилам
1. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Виконт. Книга 3. Знамена Легиона
3. Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.00