Читаем UNIX — универсальная среда программирования полностью

 extern double Pow;

 d2 = pop;

 d1 = pop;

 d1.val = Pow(d1.val, d2.val);

 push(d1);

}


assign /* assign top value to next value */

{

 Datum d1, d2;

 d1= pop;

 d2 = pop;

 if (d1.sym-type != VAR d1.sym-type != UNDEF)

  execerror("assignment to non-variable", d1.sym-name);

 d1.sym-u.val = d2.val;

 d1.sym-type = VAR;

 push(d2);

}


print /* pop top value from stack, print it */

{

 Datum d;

 d = pop;

 printf("\t%8g\n", d.val);

}


Inst *code(f) /* install one instruction or operand */

 Inst f;

{

 Inst *oprogp = progp;

 if (progp = eprog[NPROG])

  execerror("program too big", (char*)0);

 *progp++ = f;

 return oprogp;

}


execute(p) /* run the machine */

 Inst *p;

{

 for (pc = p; *pc != STOP; )

  (*(*pc++));

}

3.5.2 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;

3.5.3 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 */

#include stdio.h

#include ctype.h

char *progname;

int lineno = 1;

#include signal.h

#include setjmp.h

jmp_buf begin;


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;

}


static int c; /* global for use by warning */


yylex /* hoc4 */

{

 while ((c=getchar) == ' ' || с == '\t')

  ;

 if (c == EOF)

  return 0;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже