错误:“ yylval”外部YYSTYPE yylval的类型冲突

时间:2018-12-17 15:49:56

标签: c bison flex-lexer yacc lex

我正在尝试运行此

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; }

使用命令:

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

但是我收到此错误:

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;

去年冬天它起作用了,我不明白为什么它现在不起作用。我在ubuntu上使用lex和yacc。

1 个答案:

答案 0 :(得分:0)

如果您要使用#define重新定义YYSTYPE,那么您需要{em>之前 {em {1}}进行此操作。否则,#include <y.tab.h>将使y.tab.h成为YYSTYPE的类型别名(typedef)。由于inty.tab.h都同时声明了y.tab.c(作为yylval),因此实际上您无需在任何地方声明它,但是您仍然需要将{{ 1}}在extern YYSTYPE之前。

如果您要使用野牛,则有更方便的方法来完成#define的重新声明。最好的是放

#include

进入您的YYSTYPE文件,例如在%define api.value.type { char* } 声明之前。然后,您可以从两个文件中删除.y以及%token声明,因为bison会将适当的#define YYSTYPE放入头文件中。

您确实应该使用

编译项目
extern YYSTYPE yylval;

然后,gcc会警告您许多错误。只要您将以下内容放入lex文件,bison和flex都将生成无警告代码:

typedef

我通常也建议使用gcc -Wall lex.yy.c y.tab.c ,因为这样可以避免编写伪%option noinput nounput 的实现。