0

我在编译代码时遇到问题。

当 main() 与 yacc 解析器在同一个文件中时它可以工作,但是当我将 main() 放在另一个文件中时它不起作用。

这是我的 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; }
. ;
%%

这是我的野牛文件:(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();
    }
}
*/

这是我的主程序:(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());

}

这是我的 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

当我编译我得到这个错误。

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:我有必要用 g++ 编译。用 gcc 我有一个工作代码。

非常感谢这方面的任何帮助。

谢谢。

4

2 回答 2

2

你读过GNU Bison 的文档吗?它有一章关于C++ 解析器和一个完整的示例(与您的非常相似)。

您可以按照此答案yyparse 的建议显式声明,但制作真正的 C++ 解析器可能会更好。

Makefile的不是很好。你可以有类似的东西

  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 $<

花点时间阅读GNU make的文档。您可能想使用remake asremake -x来调试您的Makefile.

于 2013-08-03T08:31:29.393 回答
1

您需要在文件中声明yyparse函数testlex.cc

int yyparse();

这就是所谓的函数原型,它告诉编译器该函数存在并且可以调用。


在仔细查看您的源代码后,我现在知道现有原型不起作用的原因:这是因为您将其声明为extern "C"但将文件编译为 C++ 源代码。extern "C"告诉编译器该函数yyparse是旧的 C 风格函数,但随后您继续使用 C++ 编译器编译源代码。这导致名称不匹配。

于 2013-08-03T08:31:21.333 回答