Ошибка компиляции (g ++, bison, flex), когда main находится в другом файле

У меня проблема с компиляцией моего кода.

Он работает, когда 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 у меня есть рабочий код.

Любая помощь в этом отношении высоко ценится.

Благодарю.

0

Решение

Вам нужно объявлять yyparse функция в testlex.cc файл:

int yyparse();

Это то, что известно как прототип функции, и сообщает компилятору, что функция существует и может быть вызвана.


Посмотрев немного ближе к вашему источнику, я теперь знаю причину, по которой существующий прототип не работал: это потому, что вы объявили его как extern "C" но скомпилировал файл как источник C ++. extern "C" сказал компилятору, что yyparse функция была старой функцией в стиле C, но затем вы продолжили компилировать исходный код с помощью компилятора C ++. Это вызвало несоответствие имени.

1

Другие решения

Вы читали документация 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 -x отладить ваш Makefile,

2

По вопросам рекламы [email protected]