加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Bison中缀计算器总是评估为0

发布时间:2020-12-16 09:43:28 所属栏目:百科 来源:网络整理
导读:我正在读一本我在互联网上发现的关于GNU Flex / Bison的书.这很酷.其中一个例子涉及编写中缀计算器.这很好. 问题是,本书使用int作为YYSTYPE,这会产生明显的问题,比如将1除以2.所以我决定修改程序以使用float.到现在为止还挺好.该程序(源代码如下)编译得很好,
我正在读一本我在互联网上发现的关于GNU Flex / Bison的书.这很酷.其中一个例子涉及编写中缀计算器.这很好.

问题是,本书使用int作为YYSTYPE,这会产生明显的问题,比如将1除以2.所以我决定修改程序以使用float.到现在为止还挺好.该程序(源代码如下)编译得很好,但无论计算结果如何,总是给出0的答案.我也不知道如何调试它,因为它显然是生成代码.

calc.l

%{
 #include "parser.h"
 %}

 %%

 "+"                        { return ADD; }
 "-"                        { return SUB; }
 "*"                        { return MUL; }
 "/"                        { return DIV; }
 [0-9]+                     { 
                                yylval = atof(yytext); 
                                return NUMBER; 
                            }
 n                         { return EOL; }
 [ t]                      { ; }
 .                          { yyerror("Unknown symbol"); }

 %%

calc.y

%{
 #include <stdio.h>

 #define YYSTYPE float
 %}

 %token NUMBER
 %token ADD SUB MUL DIV
 %token EOL

 %%

 /* List of expressions */
 calclist: 
    | calclist AS_result EOL { printf("%fn-> ",$2); }
    ;

 /* Add/subtract result. Evaluated after multiply/divide result */
 AS_result: MD_result
    | AS_result ADD MD_result       { $$= $1 + $3; }
    | AS_result SUB MD_result       { $$= $1 - $3; }
    ;

 /* Multiply/divide result. Evaluated first. */
 MD_result: NUMBER
    | MD_result MUL NUMBER          { $$= $1 * $3; }
    | MD_result DIV NUMBER          { $$= $1 / $3; }
    ;
 %%

 int yyerror(char *msg)
 {
    printf("Error: '%s'n",msg);
    return 0;
 }

 int main(int argc,char **argv)
 {
    printf("-> ");
    yyparse();
    return 0;
 }

Makefile文件

make: calc.l calc.y
    bison -Wall -o parser.c --defines=parser.h calc.y
    flex -o scanner.c calc.l
    cc -ggdb -o calc scanner.c parser.c -lfl

 clean:
    rm -f parser.c parser.h scanner.c calc.c calc

示例运行

michael@michael-desktop:~/code/calculator$./calc 
-> 1 + 2
0.000000
-> ^C
michael@michael-desktop:~/code/calculator$

感谢代码的任何部分的反馈以及实际问题.干杯!

解决方法

你是对的,它只适用于分裂 – 奇怪……我没有注意到,对我感到羞耻.
这是另一件要尝试的事情:

calc.y:

%{
#include <stdio.h>
%}

%union { double d; }

%token <d> NUMBER
%token ADD SUB MUL DIV
%token EOL

%type <d> MD_result AS_result

%%

calc.l:更改行“yylval = atof(yytext);”有:

yylval.d = atof(yytext);

现在它说:

-> 1+2
3.000000
-> 2*3
6.000000
-> 4-5
-1.000000
-> 6/4
1.500000

正如所料.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读