Flex lexer flex和bison的实数问题

Flex lexer flex和bison的实数问题,flex-lexer,Flex Lexer,我一直在使用flex和bison制作一个小型计算器。我的文件如下: 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 fact

我一直在使用flex和bison制作一个小型计算器。我的文件如下:

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);
}
我的程序可以很好地处理整数,它也可以识别实数,但问题是当我打印一个操作的结果时,它总是以整数的形式返回答案。为什么呢


感谢您在生产中使用atoi将字符串转换为整数。 使用atof将其转换为浮点数。 如果要将两者分开,则需要更改整数的匹配规则,并为浮点添加一个匹配规则。

更改
%d
→ <代码>文件“bisonFile.y”中的“%f”。这将使用浮点格式打印结果。固定行应为:

| calclist exp EOL { printf("= %f\n", $2); }
[0-9]+("."[0-9]+)? { yylval = atof(yytext); return NUMBER; }
在文件“flexFile.l”中,删除两个定义。野牛产量

YYSTYPE yylval;
自动地
YYSTYPE
是语义值的类型。因为您需要浮点计算器,所以它应该是
double
。请注意,
YYSTYPE
默认为
int
。要改变这一点,编译C代码(来自bison和flex)时必须定义
YYSTYPE
(见下文)

最后,如MIS所述,替换
atoi()
→ <代码>atof()。flexFile.l中编辑的行应为:

| calclist exp EOL { printf("= %f\n", $2); }
[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 $@ --defines=f5.tab.h $^
l.c:                flexFile.l f5.tab.h
                    flex -o $@ $^
clean::
                    $(RM) calc calc.o calc.c f5.tab.h l.o l.c

那就行了。

我也试过了,但仍然将答案打印为整数。您应该删除
yylval
的(两个)声明。它在bison生成的C文件中定义,并在生成的bison头中声明为
extern
,因此显式声明是多余的,其中两个是双重声明。@rici:谢谢。那更干净。我会修改我的答案。