http://blog.csdn.net/haoel/article/details/4789364
初步学习了下,感觉挺好玩的,核心代码量很少,重点关注AST就好了
参考 http://blog.csdn.net/haoel/article/details/4789364 实现了一个简单的计算器
calc.y
%{
#include <stdio.h>
#define YYSTYPE double
%}
%token NUMBER
%token ADD SUB MUL DIV ABS OP CP
%token EOL
%%
calclist:
| calclist exp EOL { printf("= %f\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 exp ABS { $$ = $2 >= 0? $2 : - $2; }
| OP exp CP { $$ = $2; }
%%
main (int argc, char** argv) {
yyparse();
}
yyerror(char* s) {
fprintf(stderr, "error: %s\n", s);
}
calc.l
%{
#define YYSTYPE double
#include "calc.tab.h"
#ifdef CALC_LEX
YYSTYPE yylval;
#endif
%}
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"(" { return OP; }
")" { return CP; }
"|" { return ABS; }
"\n" { return EOL; }
[ t] { /* ignore */ }
([0-9]*\.?[0-9]+|[0-9]+\.[0-9]*) { yylval = atof(yytext); return NUMBER; }
%%
#ifdef CALC_LEX
int main(int argc, char** argv) {
int token;
while (token = yylex()) {
printf("%d", token);
if (token == NUMBER) {
printf(" = %f\n", yylval);
} else {
printf("\n");
}
}
return 0;
}
#endif
makefile
cc=gcc
calc:calc.y calc.l
bison -d calc.y
flex -o calc.lex.c calc.l
cc -o $@ calc.tab.c calc.lex.c -lfl
calc.lex: calc.y calc.l
bison -d calc.y
flex -o calc.lex.c calc.l
cc -D CALC_LEX -o $@ calc.lex.c -lfl
clean:
rm calc.lex.c
rm calc.tab.h
rm calc.tab.c
rm calc