简体   繁体   English

当main在另一个文件中时,编译错误(g ++,bison,flex)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM