2013-10-08 2 views
1

Я читаю LFS и наткнулся на bison, который я видел перед другими местами, поэтому мне показалось, что я должен немного узнать об этом. Я нашел this page from UC Riverside CS department, и код примера не работает. Кто-нибудь знает, что случилось? Для удобства я вставил код:Код примера Bison не компилируется

calc.lex файл:

/* Mini Calculator */ 
/* calc.lex */ 

%{ 
#include "heading.h" 
#include "tok.h" 
int yyerror(char *s); 
int yylineno = 1; 
%} 

digit  [0-9] 
int_const {digit}+ 

%% 

{int_const} { yylval.int_val = atoi(yytext); return INTEGER_LITERAL; } 
"+"  { yylval.op_val = new std::string(yytext); return PLUS; } 
"*"  { yylval.op_val = new std::string(yytext); return MULT; } 

[ \t]*  {} 
[\n]  { yylineno++; } 

.  { std::cerr << "SCANNER "; yyerror(""); exit(1); } 

calc.y файл:

/* Mini Calculator */ 
/* calc.y */ 

%{ 
#include "heading.h" 
int yyerror(char *s); 
int yylex(void); 
%} 

%union{ 
    int  int_val; 
    string* op_val; 
} 

%start input 

%token <int_val> INTEGER_LITERAL 
%type <int_val> exp 
%left PLUS 
%left MULT 

%% 

input:  /* empty */ 
     | exp { cout << "Result: " << $1 << endl; } 
     ; 

exp:  INTEGER_LITERAL { $$ = $1; } 
     | exp PLUS exp { $$ = $1 + $3; } 
     | exp MULT exp { $$ = $1 * $3; } 
     ; 

%% 

int yyerror(string s) 
{ 
    extern int yylineno; // defined and maintained in lex.c 
    extern char *yytext; // defined and maintained in lex.c 

    cerr << "ERROR: " << s << " at symbol \"" << yytext; 
    cerr << "\" on line " << yylineno << endl; 
    exit(1); 
} 

int yyerror(char *s) 
{ 
    return yyerror(string(s)); 
} 

здесь сообщение об ошибке:

$ make 
bison -d -v calc.y 
cp calc.tab.c bison.c 
cmp -s calc.tab.h tok.h || cp calc.tab.h tok.h 
g++ -g -Wall -ansi -pedantic -c bison.c -o bison.o 
calc.tab.c: In function ‘int yyparse()’: 
calc.tab.c:1381: warning: deprecated conversion from string constant to ‘char*’ 
calc.tab.c:1524: warning: deprecated conversion from string constant to ‘char*’ 
flex calc.lex 
cp lex.yy.c lex.c 
g++ -g -Wall -ansi -pedantic -c lex.c -o lex.o 
calc.lex:8: error: redefinition of ‘int yylineno’ 
lex.yy.c:349: error: ‘int yylineno’ previously defined here 
calc.lex: In function ‘int yylex()’: 
calc.lex:23: warning: deprecated conversion from string constant to ‘char*’ 
lex.yy.c: At global scope: 
lex.yy.c:1105: warning: ‘void yyunput(int, char*)’ defined but not used 
make: *** [lex.o] Error 1 

ответ

1

Проблема в том, что вы c ompiling C-код с компилятором C++. Если вы хотите, чтобы flex генерировал C++, для этого есть опция командной строки.

Сгенерированный сканером код содержит определение для yylineno.

В С, следующее является приемлемым:

int yylineno;   /* tentative definition */ 
int yylineno = 1;  /* definition */ 

В C++ это не так:

int yylineno;   /* definition */ 
int yylineno = 1;  /* another definition: duplicate, error! */ 

отметить также, что -ansi GCC параметр относится к C диалекте.

Предупреждения о строковых константах также из-за C++. В C++ строковый литерал, такой как "abc", вычисляет const char *, а не char *.

И, наконец, обратите внимание, что сканеры с гибким сгенерированием не будут содержать код, обновляющий yylineno. Это включено с %option yylineno. Проверьте руководство по GNU Info на Flex.

Смежные вопросы