I'm building a compiler using flex and bison, but I need the entrypoint to be in an additional file. This is giving me problems because I pretend to parse files.
The bison file looks like this:
%{
void set_file ( const char *file_path );
FILE *yyin;
%}
%%
// Boring stuff
%%
void set_file ( const char *file_path )
{
yyin = fopen(file_path, "r");
}
Meanwhile the 'main.c' file looks like this:
#include "nml.y.h"
#include <stdio.h>
int main ( int argc, char *argv[] )
{
for (int i = 1; i < argc; i++) {
set_file(argv[i]);
yyparse();
}
return 0;
}
The problem is that neither yyin nor set_file() are exposed in the generated bison.tab.h file, since they are only part of the source file, resulting in a compiler warning and, what seems to be, a very bad programming practice.
Is there any way to set the input of a yylexer from another file?
First off, the yyin
you want to set is declared and defined by the flex-generated scanner. Declaring a different one in your bison-generated parser will produce a linker error, since there can only be one external global variable with a given name. So your bison file should declare it as extern
.
But you don't want to export that declaration; the only declaration you want to export is the declaration of the set_file
function. In order to get bison to insert a declaration into the header file, you need to put the declaration inside a %code provides
block.
Putting all that together, you get:
%code {
// Don't assume this file is included
#include <stdio.h>
}
%code provides {
void set_file ( const char *file_path );
}
%%
// Grammar
%%
void set_file ( const char *file_path )
{
/* Declare yyin, found in the scanner */
extern FILE* yyin;
yyin = fopen(file_path, "r");
}
Of course, no-one really cares where you define functions. You don't need to actually put the definition of set_file
into your parser; you could put it in your scanner where you won't need an external declaration of yyin
(since it is already declared in that file). But it's still useful to put the declaration into the bison-generated header file.