2017-05-11 2 views
0

Ich habe Flex und Bison für die Herstellung eines kleinen Taschenrechners verwendet. Meine Dateien sind die folgenden:Flex und Bison Ausgabe für reelle Zahlen

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

%{ 
# 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); } 
%% 

Mein Programm arbeitet mit Integer-Zahlen in Ordnung, und es erkennt auch reelle Zahlen, aber das Problem ist, dass Wenn ich die Ergebnisse einer Operation drucke, gibt sie immer die Antwort als Ganzzahl zurück. Warum das?

Dank

Antwort

0

Ihre Verwendung bei der Herstellung von atoi wandelt den String in einen Integer. Mit atof wird es in eine Gleitkommazahl umgewandelt. Wenn Sie die beiden trennen möchten, müssen Sie die Übereinstimmungsregel für Ganzzahlen ändern und eine für Gleitkommazahl hinzufügen.

+0

Ich habe das auch schon versucht, und druckt immer noch die Antwort als eine ganze Zahl – Little

0

Ändern "%d""%f" in der Datei "bisonFile.y". Dies verwendet ein Gleitkommaformat zum Drucken des Ergebnisses. Die feste Linie sollte lauten:

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

In der Datei „flexFile.l“ int yylvalbeide Definitionen entfernen. Bison-Ausgänge

YYSTYPE yylval; 

automatisch. YYSTYPE ist die Art der semantischen Werte. Da Sie einen Fließkomma-Rechner haben möchten, muss dies double sein. Beachten Sie, dass YYSTYPE standardmäßig int ist. Um dies zu ändern, muss YYSTYPE beim Kompilieren der C-Codes (von Bison und Flex) definiert werden (siehe unten).

Schließlich, wie bereits von MIS angegeben, ersetzen atoi()atof(). Die bearbeitete Zeile in flexFile.l sollte lauten:

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

Für einen Anfänger der Abhängigkeiten zwischen Flex und Bison Quellen könnten verwirrend sein. Ein minimales Makefile dokumentiert, wie das Beispiel kompiliert werden kann. Zeile 2 legt den semantischen Typ für den Scanner und den Parser einheitlich fest:

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 

Das wird den Trick tun.

+0

Sie sollten (beide) Erklärungen 'yylval' entfernen. Es ist in der Bison-generierten C-Datei definiert und im generierten Bison-Header 'extern' deklariert, so dass eine explizite Deklaration redundant ist und zwei von ihnen doppelt so. – rici

+0

@rici: Danke. Das ist sauberer. Ich werde meine Antwort überarbeiten. – hermannk

Verwandte Themen