flex/bison テスト
構文解析って、手書きかnotavaCCでしかやったこと無い。なので一度lex/yaccなものをいじるべきだと思った。
とりあえず電卓づくり。
flexドキュメントの例ほぼそのまま。 http://www.asahi-net.or.jp/~wg5k-ickw/html/online/flex-2.5.4/flex_6.html#SEC32
整数だけの計算のときは整数演算するようにしてみた。そんだけ。
% flex -I expr.l % bison -d -y expr.y % gcc y.tab.c lex.yy.c -lfl % ./a.out 3. 3.000000 % ./a.out 3+3*2-1 8 3+3*2-0.1 8.900000 1+2+(3.0+4.0)-5 5.000000
/** * expr.l **/ %{ #include "y.tab.h" %} %% [0-9]+ { yylval.ival = atof(yytext); return(INTEGER); } [0-9]+\.[0-9]* { sscanf(yytext,"%f",&yylval.fval); return(FLOAT); } "+" return(PLUS); "-" return(MINUS); "*" return(MULT); "/" return(DIV); "(" return(LB); ")" return(RB); \n return(EOL); . { yyerror("Illegal character"); return(EOL); } %%
/** * expr.y **/ %{ #include <stdio.h> %} %union { int ival; float fval; } %token INTEGER FLOAT %token PLUS MINUS MULT DIV %token EOL %token LB RB %left MINUS PLUS %left MULT DIV %type <ival> ival INTEGER %type <fval> fval FLOAT %% input : | input line ; line : EOL | ival EOL { printf("%d\n",$1);} | fval EOL { printf("%f\n",$1);} ; fval : FLOAT { $$ = $1;} | fval PLUS fval { $$ = $1 + $3;} | fval PLUS ival { $$ = $1 + $3;} | ival PLUS fval { $$ = $1 + $3;} | fval MINUS fval { $$ = $1 - $3;} | fval MINUS ival { $$ = $1 - $3;} | ival MINUS fval { $$ = $1 - $3;} | fval MULT fval { $$ = $1 * $3;} | fval MULT ival { $$ = $1 * $3;} | ival MULT fval { $$ = $1 * $3;} | fval DIV fval { $$ = $1 / $3;} | fval DIV ival { $$ = $1 / $3;} | ival DIV fval { $$ = $1 / $3;} | MINUS fval %prec MINUS { $$ = -$2;} | LB fval RB { $$ = $2;} ; ival : INTEGER { $$ = $1;} | ival PLUS ival { $$ = $1 + $3;} | ival MINUS ival { $$ = $1 - $3;} | ival MULT ival { $$ = $1 * $3;} | ival DIV ival { $$ = $1 / $3;} | MINUS ival %prec MINUS { $$ = -$2;} | LB ival RB { $$ = $2;} ; %% int yyerror(const char *s) { fprintf(stderr, "%s\n", s); } int main() { yyparse(); }