Категории
Самые читаемые
💎Читать книги // БЕСПЛАТНО // 📱Online » Компьютеры и Интернет » Программное обеспечение » UNIX — универсальная среда программирования - Брайан Керниган

Читаем без скачивания UNIX — универсальная среда программирования - Брайан Керниган

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 89 90 91 92 93 94 95 96 97 ... 103
Перейти на страницу:

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

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

 | asgn

 | BLTIN '(' expr ')'

  { $$ = $3; code2(bltin,(Inst)$1->u.ptr); }

 | '(' expr ')' { $$ = $2; }

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

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

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

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

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

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

 | expr GT expr { code(gt); }

 | expr GE expr { code(ge); }

 | expr LT expr { code(lt); }

 | expr LE expr { code(le); }

 | expr EQ expr { code(eq); }

 | expr NE expr { code(ne); }

 | expr AND expr { code(and); }

 | expr OR expr { code(or); }

 | NOT expr { $$ = $2; code(not); }

 ;

%%

/* end of grammar */

#include <stdio.h>

#include <ctype.h>

char *progname;

int lineno = 1;

#include <signal.h>

#include <setjmp.h>

jmp_buf begin;

int defining;

int c; /* global for use by warning() */

yylex() /* hoc5 */

{

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

  ;

 if (c == EOF)

  return 0;

 if (c == '.' || isdigit(c)) { /* number */

  double d;

  ungetc(c, stdin);

  scanf("%lf", &d);

  yylval.sym = install("", NUMBER, d);

  return NUMBER;

 }

 if (isalpha(c)) {

  Symbol *s;

  char sbuf[100], *p = sbuf;

  do

   *p++ = c;

  while ((c=getchar()) != EOF && isalnum(c));

  ungetc(c, stdin);

  *p = '';

  if ((s=lookup(sbuf)) == 0)

   s = install(sbuf, UNDEF, 0.0);

  yylval.sym = s;

  return s->type == UNDEF ? VAR : s->type;

 }

 switch (c) {

 case '>': return follow('=', GE, GT);

 case '<': return follow('=', LE, LT);

 case '=': return follow('=', EQ, '=');

 case '!': return follow('=', NE, NOT);

 case '|': return follow('|', OR, '|');

 case '&': return follow('&', AND, '&');

 case 'n': lineno++; return 'n';

 default: return c;

 }

}

follow(expect, ifyes, ifno) /* look ahead for >=, etc. */

{

 int c = getchar();

 if (c == expect)

  return ifyes;

 ungetc(c, stdin);

 return ifno;

}

yyerror(s)

 char *s;

{

 warning(s, (char*)0);

}

execerror(s, t) /* recover from run-time error */

 char *s, *t;

{

 warning(s, t);

 longjmp(begin, 0);

}

fpecatch() /* catch floating point exceptions */

{

 execerror("floating point exception", (char*)0);

}

main(argc, argv)

 char *argv[];

{

 int fpecatch();

 progname = argv[0];

 init();

 setjmp(begin);

 signal(SIGFPE, fpecatch);

 for (initcode(); yyparse(); initcode())

  execute(prog);

 return 0;

}

warning(s, t)

 char *s, *t;

{

 fprintf(stderr, "%s: %s", progname, s);

 if (t && *t)

  fprintf(stderr, " %s", t);

 fprintf(stderr, " near line %dn", lineno);

 while (c != 'n' && с != EOF)

  c = getchar(); /* flush rest of input line */

 fseek(stdin, 0L, 2); /* flush rest of file */

 longjmp(begin, 0);

}

3.6.6 init.c

#include "hoc.h"

#include "y.tab.h"

#include <math.h>

extern double Log(), Log10(), Sqrt(), Exp(), integer();

static struct { /* Keywords */

 char *name;

 int kval;

} keywords[] = {

 "if",    IF,

 "else",  ELSE,

 "while", WHILE,

 "print", PRINT,

 0,       0,

};

static struct { /* Constants */

 char *name;

 double eval;

} consts[] = {

 "PI",    3.14159265358979323846,

 "E",     2.71828182845904523536,

 "GAMMA", 0.57721566490153286060, /* Euler */

 "DEG",  57.29577951308232087680, /* deg/radian */

 "PHI",   1.61803398874989484820, /* golden ratio */

 0,       0

};

static struct { /* Built-ins */

 char *name;

 double (*func)();

} builtins[] = {

 "sin",   sin,

 "cos",   cos,

 "atan",  atan,

 "log",   Log, /* checks argument */

 "log10", Log10, /* checks argument */

 "exp",   exp,

 "sqrt",  Sqrt, /* checks argument */

 "int",   integer,

 "abs",   fabs,

 0, 0

};

init() /* install constants and built-ins in table */

{

 int i;

 Symbol *s;

 for (i = 0; keywords[i].name; i++)

  install(keywords[i].name, keywords[i].kval, 0.0);

 for (i = 0; consts[i].name; i++)

  install(consts[i].name, VAR, consts[i].eval);

 for (i = 0; builtins[i].name; i++) {

  s = install(builtins[i].name, BLTIN, 0.0);

  s->u.ptr = builtins[i].func;

 }

}

3.6.7 makefile

YFLAGS = -d

OBJS = hoc.o code.o init.o math.o symbol.o

hoc5: $(OBJS)

      cc $(OBJS) -lm -o hoc5

hoc.o code.o init.o symbol.o: hoc.h

code.o init.o symbol.o: x.tab.h

x.tab.h: y.tab.h

      -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h

pr: hoc.y hoc.h code.c init.c math.c symbol.c

      @pr $?

      @touch pr

clean:

      rm -f $(OBJS) [xy].tab.[ch]

3.6.8 math.c

#include <math.h>

#include <errno.h>

extern int errno;

double errcheck();

double Log(x)

 double x;

{

 return errcheck(log(x), "log");

}

double Log10(x)

 double x;

{

 return errcheck(log10(x), "log10");

}

double Sqrt(x)

 double x;

{

 return errcheck(sqrt(x), "sqrt");

}

double Exp(x)

 double x;

{

 return errcheck(exp(x), "exp");

}

double Pow(x, y)

 double x, y;

{

 return errcheck(pow(x,y), "exponentiation");

}

double integer(x)

 double x;

{

 return (double)(long)x;

}

double errcheck(d, s) /* check result of library call */

 double d;

 char *s;

{

 if (errno == EDOM) {

  errno = 0;

  execerror(s, "argument out of domain");

 } else if (errno == ERANGE) {

  errno = 0;

  execerror(s, "result out of range");

 }

 return d;

}

3.6.9 symbol.c

#include "hoc.h"

#include "y.tab.h"

static Symbol *symlist =0; /* symbol table: linked list */

Symbol *lookup(s) /* find s in symbol table */

 char *s;

{

 Symbol *sp;

 for (sp = symlist; sp != (Symbol*)0; sp = sp->next)

  if (strcmp(sp->name, s) == 0)

   return sp;

 return 0; /* 0 ==> not found */

}

Symbol *install(s, t, d) /* install s in symbol table */

 char *s;

 int t;

 double d;

{

 Symbol *sp;

 char *emalloc();

 sp = (Symbol*)emalloc(sizeof(Symbol));

 sp->name = emalloc(strlen(s)+1); /* +1 for '' */

 strcpy(sp->name, s);

 sp->type = t;

 sp->u.val = d;

 sp->next = symlist; /* put at front of list */

 symlist = sp;

 return sp;

}

char *emalloc(n) /* check return from malloc */

 unsigned n;

{

 char *p, *malloc();

 p = malloc(n);

 if (p == 0)

  execerror("out of memory", (char*)0);

 return p;

}

3.7 hoc6

3.7.1 ack

func ack() {

 n = n+1

 if ($1 == 0) return ($2+1)

 if ($2 == 0) return (ack($1 - 1, 1))

 return (ack($1 - 1, ack($1, $2 - 1)))

}

n=0

ack(3,3)

print n, "callsn"

3.7.2 ack1

func ack() {

 n = n+1

 if ($1 == 0) return ($2+1)

 if ($2 == 0) return (ack($1 - 1, 1))

 return (ack($1 - 1, ack($1, $2 - 1)))

}

n=0

while (read(x)) {

 read(y)

 print ack(x,y), "n"

}

print n,"n"

3.7.3 code.c

#include "hoc.h"

#include "y.tab.h"

#include <stdio.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 */

Inst *progbase = prog; /* start of current subprogram */

1 ... 89 90 91 92 93 94 95 96 97 ... 103
Перейти на страницу:
На этой странице вы можете бесплатно скачать UNIX — универсальная среда программирования - Брайан Керниган торрент бесплатно.
Комментарии