[英]Compilation error (g++, bison, flex) when main is in another file
I have a problem in compiling my code. 我在编译代码时遇到问题。
It works when main() is in the same file as yacc parser but its not working when I put main() in another file. 当main()与yacc解析器在同一文件中时,它可以工作,但是当我将main()放在另一个文件中时,它就无法工作。
This is my Flex file: (lex1.ll) 这是我的Flex文件:(lex1.ll)
%{
#include <stdio.h>
#include "yac1.tab.hh"
extern "C"
{
int yylex(void);
}
int line_num = 1;
%}
alpha [A-Za-z]
digit [0-9]
%%
"DELETE ALL" return DELALL;
[ \t] ;
INSERT return INSERT;
DELETE return DELETE;
FIND return FIND;
[0-9]+\.[0-9]+ { yylval.fval = atof(yytext); return FLOAT; }
[0-9]+ { yylval.ival = atoi(yytext); return INT; }
[a-zA-Z0-9_]+ { yylval.sval = strdup(yytext);return STRING; }
\n { ++line_num; return ENDL; }
. ;
%%
This is my Bison file: (yac1.yy) 这是我的Bison文件:(yac1.yy)
%{
#include <stdio.h>
#include <stdlib.h>
int intval;
void yyerror(const char *s)
{
fprintf(stderr, "error: %s\n", s);
}
extern "C"
{
int yyparse(void);
int yylex(void);
int yywrap()
{
return 1;
}
}
%}
%token INSERT DELETE DELALL FIND ENDL
%union {
int ival;
float fval;
char *sval;
}
%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING
%%
S:T {printf("INPUT ACCEPTED....\n");exit(0);};
T: INSERT val {printf("hey insert FOUND\n");}
| DELETE val
| DELALL ENDL
| FIND val
;
val : INT ENDL {printf("hey %d\n",$1);intval=$1; }
|
FLOAT ENDL
|
STRING ENDL {printf("hey %s\n",$1);}
;
%%
/*
It works if I uncomment this block of code
int main()
{
while(1){
printf("Enter the string");
yyparse();
}
}
*/
This is my main program: (testlex.cc) 这是我的主程序:(testlex.cc)
#include <stdio.h>
#include "lexheader.h"
#include "yac1.tab.hh"
extern int intval;
main()
{
/*
char * line = "INSERT 54\n";
YY_BUFFER_STATE bp = yy_scan_string( line );
yy_switch_to_buffer(bp);
yyparse();
yy_delete_buffer(bp);
printf ("hello %d",intval);
*/
printf("Enter the query:");
//while(1)
printf ("%d\n",yyparse());
}
And this is my Makefile 这是我的Makefile
parser: lex1.ll yac1.yy testlex.cc
bison -d yac1.yy
flex --header-file="lexheader.h" lex1.ll
g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl
clean:
rm -rf *.o parser
When I compile I get this error. 编译时出现此错误。
bison -d yac1.yy
flex --header-file="lexheader.h" lex1.ll
g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl
testlex.cc: In function ‘int main()’:
testlex.cc:21:24: error: ‘yyparse’ was not declared in this scope
make: *** [parser] Error 1
PS: It is necessary for me to compile with g++.With gcc I have a working code. PS:我需要用g ++进行编译。使用gcc,我有一个有效的代码。
Any help in this regard is highly appreciated. 在这方面的任何帮助都将受到高度赞赏。
Thanks. 谢谢。
Did you read the documentation of GNU Bison ? 您是否阅读了GNU Bison的文档 ? It has a chapter about C++ parsers with a complete example (quite similar to yours). 它有一章关于C ++解析器的章节,其中有一个完整的示例(非常类似于您的示例)。
You could explicitly declare yyparse
as suggested by this answer , but making a real C++ parser is perhaps better. 您可以按照此答案的建议明确声明yyparse
,但是制作一个真正的C ++解析器可能更好。
Your Makefile
is not very good. 您的Makefile
不是很好。 You could have something like 你可能会喜欢
LEX= flex
YACC= bison
LIBES= -lfl
CXXFLAGS= -Wall
parser: lex1.o yac1.tab.o lex.yy.o testlex.o
$(LINKER.cc) -o $@ $^ $(LIBES)
lex1.cc: lex1.ll
$(LEX) --header-file="lexheader.h" $< -o $@
yac1.tag.cc: yac1.yy
$(YACC) -d $<
Take also time to read the documentation of GNU make . 还花一些时间阅读GNU make的文档。 You might want to use remake as remake -x
to debug your Makefile
. 您可能希望将remake用作remake -x
来调试Makefile
。
You need to declare the yyparse
function in the testlex.cc
file: 您需要在testlex.cc
文件中声明 yyparse
函数:
int yyparse();
This is what is known as a function prototype , and tells the compiler that the function exists and can be called. 这就是所谓的函数原型 ,它告诉编译器该函数存在并且可以被调用。
After looking a little closer at your source I now know the reason why the existing prototype didn't work: It's because you declared it as extern "C"
but compiled the file as a C++ source. 在仔细查看了源代码之后,我现在知道了现有原型无法正常工作的原因:这是因为您将其声明为extern "C"
但是将该文件编译为C ++源代码。 The extern "C"
told the compiler that the yyparse
function was an old C style function but then you continued to compile the source with a C++ compiler. extern "C"
告诉编译器yyparse
函数是一个旧的C样式函数,但随后您继续使用C ++编译器来编译源代码。 This caused a name mismatch. 这导致名称不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.