используйте bison для создания исполняемого файла, но с ошибкой

Я следил за руководством по Flex и Bison, чтобы изучить flex и bison, но я застрял. Когда я компилирую с помощью «g ++ snazzle.tab.c lex.yy.c -lfl -o snazzle», я получаю следующие сообщения об ошибках:

 snazzle.tab.c: In function ‘int yyparse()’:
 snazzle.tab.c:1403: warning: deprecated conversion from string constant to ‘char*’
 snazzle.tab.c:1546: warning: deprecated conversion from string constant to ‘char*’
 /tmp/ccFyBCBm.o: In function `yyparse':
 snazzle.tab.c:(.text+0x1e0): undefined reference to `yylex'
 collect2: ld returned 1 exit status

мой env - ubuntu 10.04 bison 2.4.1 flex 2.5.35

Так и не могу найти проблему. сначала я компилирую с помощью «bison -o snazzle.y», затем он генерирует два snazzle.tab.c и snazzle.tab.h соответственно. наконец, я компилирую "g ++ snazzle.tab.c lex.yy.c -lfl -o snazzle". мой код следующим образом:

snazzle.l
%{
#include <cstdio>
#include <iostream>
using namespace std;
#include "snazzle.tab.h" 
%}
%%
[ \t]          ;
[0-9]+\.[0-9]+ { yylval.fval = atof(yytext); return FLOAT; }
[0-9]+         { yylval.ival = atoi(yytext); return INT; }
[a-zA-Z0-9]+   {
// we have to copy because we can't rely on yytext not changing underneath us:
yylval.sval = strdup(yytext);
return STRING;
}
.              ;
%%

snazzle.y
%{
#include <cstdio>
#include <iostream>
using namespace std;

extern "C" int yylex();
extern "C" int yyparse();
extern "C" FILE *yyin;

void yyerror(char *s);
%}

%union {
int ival;
float fval;
char *sval;
}

%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING

%%

snazzle:
INT snazzle      { cout << "bison found an int: " << $1 << endl; }
| FLOAT snazzle  { cout << "bison found a float: " << $1 << endl; }
| STRING snazzle { cout << "bison found a string: " << $1 << endl; }
| INT            { cout << "bison found an int: " << $1 << endl; }
| FLOAT          { cout << "bison found a float: " << $1 << endl; }
| STRING         { cout << "bison found a string: " << $1 << endl; }
;
%%

main() {
// open a file handle to a particular file:
FILE *myfile = fopen("a.snazzle.file", "r");
// make sure it is valid:
if (!myfile) {
    cout << "I can't open a.snazzle.file!" << endl;
    return -1;
}
// set flex to read from it instead of defaulting to STDIN:
yyin = myfile;

// parse through the input until there is no more:
do {
    yyparse();
} while (!feof(yyin));
}

void yyerror(char *s) {
cout << "EEK, parse error!  Message: " << s << endl;
// might as well halt now:
exit(-1);
}

person user997948    schedule 03.11.2011    source источник
comment
Если вы не сделали что-то странное, например, определение YY_DECL или не использовали дополнительные аргументы для гибкости, yylex должен быть определен в lex.yy.c. Лучше всего предположить, что вы на самом деле не запускали flex или что он не удался, и у вас есть старый / пустой lex.yy.c, который вы случайно выбрали. Без дополнительной информации (фактические командные строки для запуска bison / flex и фактическое содержимое файлов .y и .l) я сомневаюсь, что вы получите большую помощь.   -  person Chris Dodd    schedule 04.11.2011
comment
Так и не могу найти проблему.   -  person user997948    schedule 04.11.2011


Ответы (1)


Вы определяете множество вещей как extern "C" в одном исходном файле, но не в другом - либо избавьтесь от "C", либо скопируйте эти объявления в файл .l. На самом деле, вероятно, лучше всего поместить все эти объявления в файл .h, который вы #include везде. Это не имеет ничего общего с flex / bison, это просто общая проблема C / C ++.

person Chris Dodd    schedule 04.11.2011