インターネットで見つけたGNUFlex/Bisonに関する本を読んでいます。そして、それはかなりクールです。例の1つは、中置計算機の作成です。そして、それはうまくいきます。
問題は、この本がint
asYYSTYPE
を使用していることです。これは、たとえば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;
}
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$
実際の問題だけでなく、コードの任意の部分に関するフィードバックを歓迎します。乾杯!