Next: Mfcalc Lexer, Previous: Mfcalc Rules, Up: Multi-function Calc [Contents][Index]
mfcalc
Symbol TableThe multi-function calculator requires a symbol table to keep track of the names and meanings of variables and functions. This doesn’t affect the grammar rules (except for the actions) or the Bison declarations, but it requires some additional C functions for support.
The symbol table itself consists of a linked list of records. Its definition, which is kept in the header calc.h, is as follows. It provides for either functions or variables to be placed in the table.
/* Function type. */ typedef double (*func_t) (double);
/* Data type for links in the chain of symbols. */ struct symrec { char *name; /* name of symbol */ int type; /* type of symbol: either VAR or FNCT */ union { double var; /* value of a VAR */ func_t fnctptr; /* value of a FNCT */ } value; struct symrec *next; /* link field */ };
typedef struct symrec symrec; /* The symbol table: a chain of 'struct symrec'. */ extern symrec *sym_table; symrec *putsym (char const *, int); symrec *getsym (char const *);
The new version of main
will call init_table
to initialize
the symbol table:
struct init { char const *fname; double (*fnct) (double); };
struct init const arith_fncts[] = { { "atan", atan }, { "cos", cos }, { "exp", exp }, { "ln", log }, { "sin", sin }, { "sqrt", sqrt }, { 0, 0 }, };
/* The symbol table: a chain of 'struct symrec'. */ symrec *sym_table;
/* Put arithmetic functions in table. */ static void init_table (void) { int i; for (i = 0; arith_fncts[i].fname != 0; i++) { symrec *ptr = putsym (arith_fncts[i].fname, FNCT); ptr->value.fnctptr = arith_fncts[i].fnct; } }
By simply editing the initialization list and adding the necessary include files, you can add additional functions to the calculator.
Two important functions allow look-up and installation of symbols in the
symbol table. The function putsym
is passed a name and the type
(VAR
or FNCT
) of the object to be installed. The object is
linked to the front of the list, and a pointer to the object is returned.
The function getsym
is passed the name of the symbol to look up. If
found, a pointer to that symbol is returned; otherwise zero is returned.
#include <stdlib.h> /* malloc. */ #include <string.h> /* strlen. */
symrec * putsym (char const *sym_name, int sym_type) { symrec *ptr = (symrec *) malloc (sizeof (symrec)); ptr->name = (char *) malloc (strlen (sym_name) + 1); strcpy (ptr->name,sym_name); ptr->type = sym_type; ptr->value.var = 0; /* Set value to 0 even if fctn. */ ptr->next = (struct symrec *)sym_table; sym_table = ptr; return ptr; }
symrec * getsym (char const *sym_name) { symrec *ptr; for (ptr = sym_table; ptr != (symrec *) 0; ptr = (symrec *)ptr->next) if (strcmp (ptr->name, sym_name) == 0) return ptr; return 0; }
Next: Mfcalc Lexer, Previous: Mfcalc Rules, Up: Multi-function Calc [Contents][Index]