我正在尝试运行此
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。
答案 0 :(得分:0)
如果您要使用#define
重新定义YYSTYPE
,那么您需要{em>之前 {em {1}}进行此操作。否则,#include <y.tab.h>
将使y.tab.h
成为YYSTYPE
的类型别名(typedef
)。由于int
和y.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
的实现。