error: conflicting types for ‘yylval’ extern YYSTYPE yylval

I'm trying to run this:

stark.lex

%{
#include <stdio.h>
#include "y.tab.h"
#ifndef YYSTYPE
#define YYSTYPE char*
#endif
#define INTEGER 288
extern YYSTYPE yylval;
%}

%%
[0-9]+ yylval=strdup(yytext);return NUMBER;
    ...

(\)){1} yylval=strdup(yytext);return EBRACKET;
\n
[ \t]+ ;
%%
int yywrap()
{return 1;}

stark.y

%{
#include <stdio.h>
#include <string.h>
#ifndef YYSTYPE
#define YYSTYPE char*
#endif
#define INTEGER 288

extern YYSTYPE yylval;
extern FILE* yyin;

void yyerror (const char *str);
int yylex(void);
%}

%token NUMBER IDENTIFIER KEY_VAR OPERATION SEMICOLON COMMA SIGN MINUS OBRACKET EBRACKET BG ND PLUS
%left PLUS MINUS
%left OPERATION


   %left UNARY
    %%
 ...

    int main()
{yyin = fopen("prog.txt","r");
yyparse();
fclose(yyin);
return 0; }

with command:

yacc -d stark.y && lex stark.lex && gcc lex.yy.c y.tab.c

But i'm getting this error:

stark.lex:15:16: error: conflicting types for ‘yylval’
 extern YYSTYPE yylval;
                ^~~~~~
In file included from stark.lex:5:0:
y.tab.h:88:16: note: previous declaration of ‘yylval’ was here
 extern YYSTYPE yylval;

It worked last winter and i can't undestand why it doesn't work now. I'm using lex and yacc on ubuntu.

Upvotes: 0

Views: 2792

Answers (1)

rici
rici

Reputation: 241911

If you're going to use #define to redefine YYSTYPE, then you need to do it before you #include <y.tab.h>. Otherwise, y.tab.h will make YYSTYPE a type alias (typedef) for int. Since both y.tab.h and y.tab.c also declare yylval (as extern YYSTYPE), there is actually no need for you to declare it anywhere, but you still need to put the #define before the #include.

If you use bison, there are much better (and more convenient) ways to declare of YYSTYPE. The best one is to put

%define api.value.type { char* }

into your .y file, for example just before the %token declaration. Then you can remove the #define YYSTYPE from both files, as well as the extern YYSTYPE yylval; declarations, since bison will put an appropriate typedef into the header file.

You really should compile your project with

gcc -Wall lex.yy.c y.tab.c

Then gcc will warn you about many mistakes. Both bison and flex will produce warning-free code, provided you put the following into your lex file:

%option noinput nounput

I usually recommend using %option noyywrap as well, since that will allow you to avoid having to write a dummy yywrap implementation.

Upvotes: 1

Related Questions