よくある、BisonとFlexを使った四則演算
カッコはまだ実装してない
しかも、抽象構文木も作ってないし、ABSの実装も適当
ただ、優先度つけてるだけ
mycalc.y
%{
#include<stdio.h>
%}
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist:
| 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; }
;
%%
int main (int argc, char** argv)
{
yyparse();
return 0;
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
んで、これをBisonにかける
bison -d mycalc.y
mycalc.tab.hが出来るので、中身を見ると以下の記述が出来ている。
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
NUMBER = 258,
ADD = 259,
SUB = 260,
MUL = 261,
DIV = 262,
ABS = 263,
EOL = 264
};
#endif
%tokenから定義が作られる。
つぎに字句解析部
mycalc.l
%{
#include "mycalc.tab.h"
int yylval;
%}
%%
"+" { return ADD;}
"-" { return SUB;}
"*" { return MUL;}
"/" { return DIV;}
"|" { return ABS;}
[0-9]+ { yylval = atoi(yytext); return NUMBER;}
\n { return EOL;}
[ \t] {}
. {printf("Mystery character %c\n", *yytext);}
%%
さきほどbisonが吐き出したmycalc.tab.hをincludeして、
ADDやSUBなどを返すのが主な仕事
値はyylvalに入れて、NUMBERを返すようになっている。
こっちにはmain関数は無い
flexでlex.yy.cを作る
flex mycalc.l
んで、lex.yy.cを見てみると、すげー長いコードが出来ていて、
こんな字句解析要る?ってみんな思うし、
自分で作ったほうがよくね?と話題になったりする。
最後にまとめる
cc -o mycalc XQParser.tab.c lex.yy.c -lfl
./mycalc
1+2
= 3
3+3
= 6
1+2+3*4/2
= 9
まぁ一応動くのが出来る。
ここまで、Bison And Flexのコードなんだけど、
ABS動かないよね、なんじゃこれ状態?
0 件のコメント:
コメントを投稿