Литмир - Электронная Библиотека
Содержание  
A
A

 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

makefile

hoc2: hoc.o

      cc hoc.o -o hoc2

3.3

hoc3

3.3.1

makefile

YFLAGS = -d # force creation of y.tab.h

OBJS = hoc.o init.o math.o symbol.o # abbreviation

hoc3: $(OBJS)

      cc $(OBJS) -lm -o hoc3

hoc.o: hoc.h

init.o symbol.o: hoc.h y.tab.h

pr:

      @pr hoc.y hoc.h init.c math.c symbol.c makefile

clean:

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

3.3.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();

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); }

147
{"b":"248117","o":1}