У меня проблема с компиляцией моего кода.
Он работает, когда 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 у меня есть рабочий код.
Любая помощь в этом отношении высоко ценится.
Благодарю.
Вам нужно объявлять yyparse
функция в testlex.cc
файл:
int yyparse();
Это то, что известно как прототип функции, и сообщает компилятору, что функция существует и может быть вызвана.
Посмотрев немного ближе к вашему источнику, я теперь знаю причину, по которой существующий прототип не работал: это потому, что вы объявили его как extern "C"
но скомпилировал файл как источник C ++. extern "C"
сказал компилятору, что yyparse
функция была старой функцией в стиле C, но затем вы продолжили компилировать исходный код с помощью компилятора C ++. Это вызвало несоответствие имени.
Вы читали документация 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
,