2013-10-08 76 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用C++編譯器編寫C代碼。如果你想讓flex生成C++,那麼有一個命令行選項。

掃描器生成的代碼已經提供了yylineno的定義。

在C中,以下是可以接受的:

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

在C++中,這不是:

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

還要注意,-ansi GCC選項適用於C方言。

有關字符串常量的警告也是因爲C++。在C++中,像​​這樣的字符串文字的計算結果爲const char *,而不是char *

最後,請注意,flex生成的掃描程序不會自動包含更新yylineno的代碼。這是用%option yylineno開啓的。檢查Flex上的GNU信息手冊。