2013-01-22 5 views
4

부동 소수점 연산을 수행 할 수있는 flex/bison 계산기를 구현하려고합니다. 내 플렉스 코드는이숫자를 float으로 해석하는 flex/bison

%{ 
#include "calc.tab.h" 
#include <stdlib.h> 

void yyerror(char *s); 
%} 

digit [0-9] 
integer {digit}+ 
real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+) 
exp ({integer}|{real})[eE]-?{integer} 

%% 

({integer}|{real}|{exp}) { yylval = atof(yytext); return NUMBER; } 
[-+*/\n]     { return *yytext; } 
[ \t\v\f\r]    { } 
.      { yyerror("Unknown Character"); } 

%% 

int yywrap(void) 
{ 
    return 1; 
} 

처럼 보인다 그리고 내 들소 코드는 오른쪽 출력을 생성하지 않습니다이

%{ 
#include <stdio.h> 

typedef double YYSTYPE; 
#define YYSTYPE_IS_DECLARED 

void yyerror(char *s); 
extern char *yytext; 
extern int yylineno; 
%} 

%token NUMBER 

%left '+' '-' 
%left '*' '/' 

%% 

program: program expr '\n' { printf("%g\n", $2); } 
     | program '\n' 
     | 
     ; 
expr: expr '+' expr { $$ = $1 + $3; } 
    | expr '-' expr { $$ = $1 - $3; } 
    | expr '*' expr { $$ = $1 * $3; } 
    | expr '/' expr { $$ = $1/$3; } 
    | NUMBER { $$ = $1; } 
    ; 

%% 

void yyerror(char *s) 
{ 
    fprintf(stderr, "error: %s at %s, line %d\n", s, yytext, yylineno); 
} 

int main(int argc, char *argv[]) 
{ 
    yyparse(); 

    return 0; 
} 

이처럼 보인다. 렉서가 문자열을 복소수로 해석하고 yylval 변수에 올바르게 저장하더라도 파서가 숫자를 더하면 0.0000 만 뱉어냅니다. 나는 오직 하나의 double lf_val; 변수로 구성된 %union 지침을 통해 조합으로 yylval을 선언하고 렉서에 yylval의이 분야에서 atof 출력을 저장하고 또한 파서 %token <lf_val> NUMBER%type <lf_val> expr를 선언 할 경우, 일이 일 것으로 보인다.

그러나 YYSTYPE을 작성하는 간단한 방법은 왜 typedef이 아닙니까? 나는 또한 #define YYSTYPE double을 시도했다. 그것도 작동하지 않았다.

답변

5

에 관한 %code, Bison's documentation 상태 :

: 당신은 이러한 두 줄을 제거 할 것

%code requires 
    { 
    #define YYSTYPE double 
    } 

:

%code requires [...] is the best place to override Bison's default YYSTYPE 
and YYLTYPE definitions. 

그래서 juste 당신의 상단에 들소 파일에 다음을 추가

typedef double YYSTYPE; 
#define YYSTYPE_IS_DECLARED 

YYSTYPE_IS_DECLARED는 내가 아는 한, 어디에도 문서화되어 있지 않으므로 Bison의 내부 용으로 만 사용됩니다.

간단한 %{ 프롤로그보다 Bison의 %code 명령어를 사용하는 데 익숙하지 않은 경우 this section of the documentation 흥미로운 것을 발견 할 수 있습니다.

+0

감사합니다. @yroeht. 나는'% code requires {}'지시자 안에'# define '을 묶는 것이 렉서에 포함 된'.h' 파일에 YYSTYPE 정의를 생성했다는 것을 알아 차렸다. 따라서 구문 분석기가 double에서 읽는 동안 렉서가 정수 변수에 쓰는 중이었습니다! – borncrusader

관련 문제