| expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { if ($3 == 0.0) execerror("division by zero", ""); $$ = $1 / $3; } | expr '^' expr { $$ = Pow($1, $3); } | '(' expr ')' { $$ = $2; } | '-' expr %prec UNARYMINUS { $$ = -$2; } ;%%/* 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) /* hoc3 */ char *argv[];{ int fpecatch(); progname = argv[0]; init(); setjmp(begin); signal(SIGFPE, fpecatch); yyparse();}yylex() /* hoc3 */{ 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 (isalpha(c)) { Symbol *s; char sbuf[100], *p = sbuf; do { *p++ = c; } while ((c=getchar()) != EOF && isalnum(c)); ungetc(c, stdin); *p = '\0'; if ((s=lookup(sbuf)) == 0) s = install(sbuf, UNDEF, 0.0); yylval.sym = s; return s->type == UNDEF ? VAR : s->type; } if (c == '\n') lineno++; return c;}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);}warning(s, t) char *s, *t;{ fprintf(stderr, "%s: %s", progname, s); if (t && *t) fprintf (stderr, " %s", t); fprintf(stderr, " near line %d\n", lineno);}3.3.4
init.c#include "hoc.h"#include "y.tab.h"#include <math.h>extern double Log(), Log10(), Exp(), Sqrt(), integer();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 */