Next: Mfcalc Main, Previous: Mfcalc Symbol Table, Up: Multi-function Calc [Contents][Index]
mfcalc
LexerThe function yylex
must now recognize variables, numeric values, and
the single-character arithmetic operators. Strings of alphanumeric
characters with a leading letter are recognized as either variables or
functions depending on what the symbol table says about them.
The string is passed to getsym
for look up in the symbol table. If
the name appears in the table, a pointer to its location and its type
(VAR
or FNCT
) is returned to yyparse
. If it is not
already in the table, then it is installed as a VAR
using
putsym
. Again, a pointer and its type (which must be VAR
) is
returned to yyparse
.
No change is needed in the handling of numeric values and arithmetic
operators in yylex
.
#include <ctype.h>
int yylex (void) { int c; /* Ignore white space, get first nonwhite character. */ while ((c = getchar ()) == ' ' || c == '\t') continue; if (c == EOF) return 0;
/* Char starts a number => parse the number. */ if (c == '.' || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval.NUM); return NUM; }
Bison generated a definition of YYSTYPE
with a member named
NUM
to store value of NUM
symbols.
/* Char starts an identifier => read the name. */ if (isalpha (c)) { /* Initially make the buffer long enough for a 40-character symbol name. */ static size_t length = 40; static char *symbuf = 0; symrec *s; int i;
if (!symbuf) symbuf = (char *) malloc (length + 1); i = 0; do
{ /* If buffer is full, make it bigger. */ if (i == length) { length *= 2; symbuf = (char *) realloc (symbuf, length + 1); } /* Add this character to the buffer. */ symbuf[i++] = c; /* Get another character. */ c = getchar (); }
while (isalnum (c)); ungetc (c, stdin); symbuf[i] = '\0';
s = getsym (symbuf); if (s == 0) s = putsym (symbuf, VAR); *((symrec**) &yylval) = s; return s->type; } /* Any other character is a token by itself. */ return c; }
Next: Mfcalc Main, Previous: Mfcalc Symbol Table, Up: Multi-function Calc [Contents][Index]