Search code examples
yacc

How to redefine `YYSTYPE` in `bison/yacc`?


I define a user class to hold all object. But the yacc is going to made a header file, which the yylval's type must be YYSTYPE. If I do not use %union, it will hold it as a int. But if I use %union, it will a union. and union is ugly - It cannot hold a class or a shared_ptr (can but not a good idea), It only want me to use pointer.

I just want to make YYSTYPE has a type as a user class type. How can I do it?


Solution

  • Don't use YYSTYPE.

    With bison -- which is what you are actually using as a yacc implementation-- the correct way to define the semantic value type is

    %define api.value.type { MyType }
    

    If you require that one or more header files be included for the declaration to be valid, put them inside a %code requires block:

    %code requires {
       #include "MyType.h"
    }
    

    The code generated by these two directives is copied into the header file which bison produces, so other files need only include the generated header file.

    Warning: Note that unless you use bison's C++ interface, the semantic value type must be trivially copyable, which will eliminate most standard C++ library types. Failing to obey this rule will produce undefined behaviour which may go undetected until you attempt to parse a sufficiently complex input. In other words, tests with simple inputs may not reveal the bug.