Dylan_Larkin Dylan_Larkin - 11 months ago 68
C Question

pointing yyin to a FILE* inside of mfcalc example

EDIT: the answer below is NOT what I'm looking for. I implemented it myself and it still doesn't read from the file (though it does compile - I had this solution already).

I'm working on the Bison mfcalc example here:

I would like to be able to read from a file, rather than stdin. I have their example up and running, but because they've redefined yylex(), getting the parser to read from a file isn't as simple as it usually is.

Anyone that can help would be greatly appreciated!

PS. Something like this: http://beej.us/guide/bgc/output/html/multipage/getc.html
But I'm not so good with C. I'll be trying to implement this in the meantime.

So you would need to modify this:

yylex (void)
int c;

/* Ignore white space, get first nonwhite character. */
while ((c = getchar ()) == ' ' || c == '\t')

if (c == EOF)
return 0;
/* Char starts a number => parse the number. */
if (c == '.' || isdigit (c))
ungetc (c, stdin);
scanf ("%d", &yylval.NUM);
return NUM;

/* 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;
/* 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;

Answer Source

This has nothing to do with bison.

In C getchar reads from stdin. If you want to use a different FILE *, use getc instead. So go over the yylex code you have above and replace getchar() with getc(yyin) (or whatever the name of your FILE * is), as well as replacing all the other references to stdin with yyin. Similarly, scanf reads from stdin and fscanf reads from a different FILE *