2013-10-08 4 views
1

저는 LFS를 읽고 다른 곳보다 먼저 보았던 bison을 보았습니다. 그래서 나는 그것에 대해 조금 더 배워야한다고 생각했습니다. this page from UC Riverside CS department을 찾았고 예제 코드가 작동하지 않습니다. 누구 잘못 알지?들소 예제 코드가 컴파일되지 않습니다

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 파일 :

$ 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 
: 여기
/* 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)); 
} 

오류 메시지입니다 편의를 위해 내가 코드를 붙여

답변

1

문제는 당신이 c C++ 컴파일러로 C 코드 ompiling. flex에서 C++을 생성하려면 명령 행 옵션이 필요합니다.

스캐너 생성 코드는 이미 yylineno에 대한 정의를 제공합니다. 다음 C에서

이 허용됩니다 : C++에서

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

, 그것은되지 않습니다 :

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

는 또한 -ansi GCC 옵션은 C 방언에 적용됩니다.

문자열 상수에 대한 경고는 C++ 때문이기도합니다. C++에서 "abc"과 같은 문자열 리터럴은 char *이 아니라 const char *으로 평가됩니다.

마지막으로 플렉스 생성 스캐너에는 yylineno을 업데이트하는 코드가 자동으로 포함되지 않습니다. 그것은 %option yylineno으로 켜져 있습니다. Flex의 GNU Info 매뉴얼을 확인하십시오.

관련 문제