Чтение онлайн

на главную - закладки

Жанры

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
:

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

Перекрестки миров. Том 2

Джек из тени
2. Майор Барон
Фантастика:
боевая фантастика
рпг
фантастика: прочее
попаданцы
5.00
рейтинг книги
Перекрестки миров. Том 2

Старая школа рул

Ромов Дмитрий
1. Второгодка
Фантастика:
альтернативная история
6.00
рейтинг книги
Старая школа рул

Статьи

Переслегин Сергей Борисович
Документальная литература:
публицистика
5.00
рейтинг книги
Статьи

Дважды одаренный. Том VIII

Тарс Элиан
8. Дважды одаренный
Фантастика:
боевая фантастика
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Дважды одаренный. Том VIII

Последний Паладин. Том 6

Саваровский Роман
6. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 6

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Идеальный мир для Лекаря

Сапфир Олег
1. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря

На границе империй. Том 5

INDIGO
5. Фортуна дама переменчивая
Фантастика:
боевая фантастика
попаданцы
7.50
рейтинг книги
На границе империй. Том 5

Наследие Маозари

Панежин Евгений
1. Наследие Маозари
Фантастика:
рпг
попаданцы
аниме
5.80
рейтинг книги
Наследие Маозари

Император Пограничья 1

Астахов Евгений Евгеньевич
1. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 1

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Идиот

Достоевский Федор Михайлович
Проза:
классическая проза
русская классическая проза
9.30
рейтинг книги
Идиот

Кодекс Крови. Книга ХVII

Борзых М.
17. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVII

Кодекс Охотника. Книга XXXVII

Винокуров Юрий
37. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVII