2013-10-08 34 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信息手册。