我正在阅读我在 Internet 上找到的关于 GNU Flex/Bison 的书。这很酷。其中一个示例涉及编写中缀计算器。这很好。
问题是,这本书使用int
as YYSTYPE
,这会在例如将 1 除以 2 时产生明显的问题。所以我决定修改程序以改为使用float
。到目前为止,一切都很好。该程序(源代码如下)编译得很好,但总是给出 0 的答案,无论计算是什么。我也不知道如何调试它,因为它显然是生成的代码。
计算器
%{
#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"); }
%%
钙质
%{
#include <stdio.h>
#define YYSTYPE float
%}
%token NUMBER
%token ADD SUB MUL DIV
%token EOL
%%
/* List of expressions */
calclist:
| calclist AS_result EOL { printf("%f\n-> ", $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;
}
生成文件
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$
对代码的任何部分以及实际问题的反馈表示赞赏。干杯!