%{ #include "calcvar.h" #include %} %union { double dval; struct symtab *symp; } %token NAME %token NUMBER %left '-' '+' %left '*' '/' %nonassoc UMINUS %type expression %% statement_list: statement '\n' | statement_list statement '\n' ; statement: NAME '=' expression { $1->value = $3; } | expression { printf("= %g\n", $1); } ; expression: expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { if($3 == 0.0) yyerror("divide by zero"); else $$ = $1 / $3; } | '-' expression %prec UMINUS { $$ = -$2; } | '(' expression ')' { $$ = $2; } | NUMBER | NAME { $$ = $1->value; } ; %% #include extern FILE *yyin; /* look up a symbol table entry, add if not present */ struct symtab * symlook(s) char *s; { char *p; struct symtab *sp; for(sp = symtab; sp < &symtab[NSYMS]; sp++) { /* is it already here? */ if(sp->name && !strcmp(sp->name, s)) return sp; /* is it free */ if(!sp->name) { sp->name = strdup(s); return sp; } /* otherwise continue to next */ } yyerror("Too many symbols"); exit(1); /* cannot continue */ } /* symlook */ yyerror(s) char *s; { fprintf(stderr,"%d\n",s); } main () { do { yyparse(); } while (!feof(yyin)); }