int fpecatch(); progname = argv[0]; setjmp(begin); signal(SIGFPE, fpecatch); yyparse();}yylex() /* hoc2 */{ int c; while ((c=getchar()) == ' ' || c == '\t') ; if (c == EOF) return 0; if (c == '.' || isdigit(c)) { /* number */ ungetc(c, stdin); scanf("%lf", &yylval.val); return NUMBER; } if (islower(c)) { yylval.index = c - 'a'; /* ASCII only */ return VAR; } if (c == '\n') lineno++; return c;}yyerror(s) /* report compile-time error */ 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);}warning(s, t) /* print warning message */ char *s, *t;{ fprintf(stderr. "%s: %s", progname, s); if (t && *t) fprintf(stderr, " %s , t); fprintf(stderr, " near line %d\n", lineno);}3.2.2
makefilehoc2: hoc.o cc hoc.o -o hoc23.3
hoc33.3.1
makefileYFLAGS = -d # force creation of y.tab.hOBJS = hoc.o init.o math.o symbol.o # abbreviationhoc3: $(OBJS) cc $(OBJS) -lm -o hoc3hoc.o: hoc.hinit.o symbol.o: hoc.h y.tab.hpr: @pr hoc.y hoc.h init.c math.c symbol.c makefileclean: rm -f $(OBJS) y.tab.[ch]3.3.2
hoc.htypedef 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();3.3.3
hoc.y%{#include "hoc.h"extern double Pow();%}%union { double val; /* actual value */ Symbol *sym; /* symbol table pointer */}%token <val> NUMBER%token <sym> VAR BLTIN UNDEF%type <val> expr asgn%right '=' %left '+' '-'%left '*' '/'%left UNARYMINUS%right /* exponentiation */%%list: /* nothing */ | list '\n' | list asgn '\n' | list expr '\n' { printf("\t%.8g\n", $2); } | list error '\n' { yyerrok; } ;asgn: VAR '=' expr { $$=$1->u.val=$3; $1->type = VAR; } ;expr: NUMBER | VAR { if ($l->type == UNDEF) execerror("undefined variable", $1->name); $$ = $1->u.val; } | asgn | BLTIN '(' expr ')' { $$ = (*($1->u.ptr))($3); }