%{ /* * exp32.y * bison -d -v exp3.y * exp3.tab.c exp3.tab.h */ #include #include /* For math functions, cos(), sin(), etc. */ #include #include #include #include "calc.h" /* Contains definition of `symrec' */ void yyerror(char const *s); %} %union { double val; /* For returning numbers. */ symrec *symTabPtr; /* For returning symbol-table pointers */ } %token NUM /* Simple double precision number */ %token VAR FUN1 FUN2 /* Variable and Function */ %type exp %right '=' %left '-' '+' %left '*' '/' %left NEG /* Negation--unary minus */ %right '^' /* Exponentiation */ /* Grammar follows */ %% input: /* empty */ | input line ; line: '\n' | exp '\n' { printf ("(val): %f\n", $1); } | error '\n' { yyerrok; } ; exp: NUM { $$ = $1; } | VAR { $$ = $1->value.var; } | VAR '=' exp { $$ = $3; $1->value.var = $3; } | FUN1 '(' exp ')' { $$ = (*($1->value.funPtr))($3); } | FUN2 '(' exp ',' exp ')' { $$ = (*($1->value.funPtr))($3, $5); } | exp '+' exp { $$ = $1 + $3; } | exp '-' exp { $$ = $1 - $3; } | exp '*' exp { $$ = $1 * $3; } | exp '/' exp { $$ = $1 / $3; } | '-' exp %prec NEG { $$ = -$2; } | '(' exp ')' { $$ = $2; } ; // End of grammar %% // The symbol table: a chain of `struct symrec'. symrec *sym_table = (symrec *)0; // Initialize the symtab with math library function names. struct initFun { char *fname; double (*fnct)(); int argC; } funName[] = { {"sin", sin, 1}, {"cos", cos, 1}, {"atan", atan, 1}, {"ln", log, 1}, {"exp", exp, 1}, {"sqrt", sqrt, 1}, {"pow",pow, 2}, {0, 0, 0} }; struct initConst { char *cname; double cval; } consName[] = { {"pi", 3.14159265358979323846}, {"e", 2.7182818284590452354}, {NULL, 0.0} } ; void init_table () { int i, type; symrec *ptr; for (i = 0; funName[i].fname != NULL; i++) { if(funName[i].argC == 1) type = FUN1; else type = FUN2; ptr = putsym (funName[i].fname, type); ptr->value.funPtr = funName[i].fnct; } for(i=0; consName[i].cname != NULL; ++i){ ptr = putsym(consName[i].cname, VAR); ptr->value.var = consName[i].cval; } } int main () { init_table (); return yyparse (); } symrec *putsym (char *sym_name, int sym_type) { symrec *ptr; ptr = (symrec *) malloc (sizeof (symrec)); ptr->name = (char *) malloc (strlen (sym_name) + 1); strcpy (ptr->name,sym_name); ptr->type = sym_type; ptr->next = (struct symrec *)sym_table; sym_table = ptr; return ptr; } void yyerror (char const *s) { printf ("%s\n", s); }