1
votes

Is there a regular way to access the function yyget_out(scanner) or the variable yyout from a reentrant Bison-generated parser?

I want to write a message to the lexer's yyout while in the parser using either

fprintf(yyout, message);

or

fprintf(yyget_out(scanner), message);

The latter actually worked, but I had to provide the prototype, FILE* yyget_out(yyscan_t), and it feels odd to do this manually rather than by including a header file.

1

1 Answers

0
votes

You can ask Flex to generate a header file with --header-file=FILE on the command line, or %option header-file="FILE" in the prologue.

However, when you try to use that header file, you'll find that it requires definitions of YYSTYPE and YYLTYPE, which are defined in the header file generated by Bison. That header file is not included in the Flex-generated header file, so you have to make sure that it is already included, or (my preference) wrap the header file inside your own header file which includes both Bison and Flex generated headers.

That's fine for other translation units, but the circular dependency between the Bison- and Flex-generated header files will still cause problems in the Bison-generated C file itself. My preferred solution is to wrap functions which use facilities provided by the Flex-generated code, and place the wrapped functions in a separate translation unit containing utilities. (The wrapping can serve other purposes, such as hiding the Flex- and Bison-specific context objects inside a more general context object which also contains context required by your project.) Trying to #include the Flex-generated header directly in your Bison file can drive you crazy.

There is still an unresolvable circularity because the Bison-generated C file is likely to depend on yyscan_t, which is declared in the Flex-generated header. There doesn't seem to be any way around this other than putting

typedef void* yyscan_t;

into the Bison code prologue (but not in a place where it will be added to the header file).

There's a longer discussion of the circular dependency problem and ways to cope with it in my answer to this question.