Search code examples
c++bisonflex-lexer

cast from ‘SymbolInfo*’ to ‘YYSTYPE {aka int}’ loses precision


In my .l file, I have the following:

<some include files....>
#include "SymbolInfo.h"
#include "y.tab.h"

using namespace std;

int line_count = 1;
int TOTAL_ERROR = 0;

extern SymbolTable symbolTable;
extern FILE *yyin,*yyout;
extern YYSTYPE yylval;

<further declarations...>

%%

"int"    {
            SymbolInfo* s = new SymbolInfo(string(yytext),"INT");
            yylval = (YYSTYPE)s;
            return INT;
         }

<more patterns....>

%%

In my .y file, I have the defined the YYSTYPE:

#include "SymbolInfo.h"

int SymbolTable::id = 0;

#define YYSTYPE SymbolInfo*

But when I try to compile it, it gives the following error:

Lexical Analyzer.l: In function ‘int yylex()’:
Lexical Analyzer.l:162:27: error: cast from ‘SymbolInfo*’ to ‘YYSTYPE {aka int}’ loses precision [-fpermissive]
         yylval = (YYSTYPE)res;
                       ^

My question is, why is it giving a compilation error even after defining YYSTYPE as SymbolInfo*? How can I handle this error ?

  1. SymbolInfo Code
  2. Parser Code
  3. Lexer Code

Solution

  • why is it giving a compilation error even after defining YYSTYPE as SymbolInfo*?

    Because, as you say, you are defining YYSTYPE in the parser definition. The error is occurring in the scanner definition. Those are separate files and macros defined in one will not be visible in the other.

    You could put the #define YYSTYPE line in your .l file before you include the header file generated by bison. Or you could put it in a %code requires section in your bison file, so that it get inserted into the bison-generated header.

    But what you should do is to avoid the macro and use a bison declaration:

    %define api.value.type { SymbolInfo* }
    

    That will not only correctly define the semantic type, it will also be placed into the bison-generated header file so that you don't have to worry about define YYSTYPE in other source files (as long as they #include the bison header file).

    Please don't use bison's -y option. It's only appropriate for legacy code. New code should be written to the bison interface. Unless otherwise specified, this will bison (without the -y flag) will put the generated code in <name>.tab.c and the header file in <name>.tab.h. If you are generating C++, you probably want to specify the output filename with --output (or -o), and if necessary specify the header filename with --defines (instead of -d; --defines lets you specify a filename). See Bison options for details.