我正在閱讀我在互聯網上找到的關於GNU Flex/Bison的書。這很酷。其中一個例子涉及編寫一箇中綴計算器。那很好。Bison中綴計算器始終評估爲0
的問題是,書中使用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("%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
實施例R上的代碼的任何部分未
[email protected]:~/code/calculator$ ./calc
-> 1 + 2
0.000000
-> ^C
[email protected]:~/code/calculator$
反饋理解以及實際問題。乾杯!
太棒了!謝謝你,它完美的作品。我不完全確定*爲什麼*它的功能完美,但我會研究這一點。 – 2013-03-24 18:22:21
基本上,我只是創建了NUMBER標記,並且分析樹的節點返回了,這是一個雙精度值,如*%union *中所指定的那樣。可能還有其他方法可以做到這一點(我的yacc比較安靜);你可以搜索「野牛簡單計算器」,如果你想要更多的例子.. –
2013-03-24 19:44:38
是的,我聚集了。我的意思是爲什麼原稿不起作用。不管怎麼說,還是要謝謝你。 :) – 2013-03-24 20:03:52