2017-05-11 6 views
0

私はフレックスとバイソンを使って小さな電卓を作っています。私のプログラムは整数で正常に動作し、それはまた、実数を認識しますが、問題があることである 実数のフレックスとバイソンの問題

%{ 
# include "f5.tab.h" 
int yylval; 
%} 
/* reconocimiento de tokens e impresion */ 
%{ 
int yylval; 
%} 
%option noyywrap 
%% 
"+" { return ADD; } 
"-" { return SUB; } 
"*" { return MUL; } 
"/" { return DIV; } 
"|" { return ABS; } 
[0-9]+("."[0-9]+)? { yylval = atoi(yytext); return NUMBER; } //part added 
\n { return EOL; } 
[ \t] { /* ignore whitespace */ } 
. { printf("Mystery character %c\n", *yytext); } 
%% 

bisonFile.y

%{ 
#include <stdio.h> 
%} 
/* declare tokens */ 
%token NUMBER 
%token ADD SUB MUL DIV ABS 
%token EOL 
%% 
calclist: /* nothing */ 
| calclist exp EOL { printf("= %d\n", $2); } 
; 
exp: factor 
| exp ADD factor { $$ = $1 + $3; } 
| exp SUB factor { $$ = $1 - $3; } 
; 
factor: term 
| factor MUL term { $$ = $1 * $3; } 
| factor DIV term { $$ = $1/$3; } 
; 
term: NUMBER 
| ABS term { $$ = $2 >= 0? $2 : - $2; } 
; 
%% 
main(int argc, char **argv) 
{ 
yyparse(); 
} 
yyerror(char *s) 
{ 
fprintf(stderr, "error: %s\n", s); 
} 

flexFile.l

:私のファイルは、以下のとおりであります操作の結果を出力すると、常に整数値として返されます。何故ですか?

ありがとうございました

答えて

0

本番でatoiを使用すると、文字列が整数に変換されます。 atofを使用すると、浮動小数点数に変換されます。 2つを分けたい場合は、整数のマッチングルールを変更し、浮動小数点を追加する必要があります。

+0

これもやってみましたが、依然として答えを整数として出力します。 – Little

0

"%d""%f"ファイル "bisonFile.y"に変更してください。これは、結果を出力するために浮動小数点形式を使用します。固定回線は次のようになります。ファイルで

| calclist exp EOL { printf("= %f\n", $2); } 

を「flexFile.lは」両方定義int yylvalを削除します。バイソンの出力

YYSTYPE yylval; 

自動的に。 YYSTYPEは意味値の型です。浮動小数点計算機が必要なので、これはdoubleとなります。 YYSTYPEのデフォルトはintです。これを変更するには、Cコードをコンパイルするときに(bisonとflexから)YYSTYPEを定義する必要があります(下記参照)。

最後に、MISですでに述べたように、atoi()atof()を置き換えます。 flexFile.lで編集した行は次のようになります初心者のために

[0-9]+("."[0-9]+)? { yylval = atof(yytext); return NUMBER; } 

はflexとbisonソース間の依存関係が混乱するかもしれません。最小限のMakefileは、サンプルがどのようにコンパイルされるかを文書化しています。 2行目は、スキャナとパーサーのセマンティックタイプを一貫して設定します。

calc:    calc.o l.o 
calc.o l.o:   CFLAGS+=-DYYSTYPE=double 
l.o:    l.c f5.tab.h 
calc.c f5.tab.h: bisonFile.y 
        bison -o [email protected] --defines=f5.tab.h $^ 
l.c:    flexFile.l f5.tab.h 
        flex -o [email protected] $^ 
clean:: 
        $(RM) calc calc.o calc.c f5.tab.h l.o l.c 

これはそのトリックです。

+0

'yylval'の宣言を削除する必要があります。 bison生成のCファイルで定義され、生成されたbisonヘッダに 'extern'が宣言されているため、明示的な宣言は冗長であり、そのうち2つは重複しています。 – rici

+0

@rici:ありがとう。それはきれいだ。私は私の答えを書き直します。 – hermannk

関連する問題