Шрифт:
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 = '\0';
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 %d\n", 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[] = {