您的位置:首页 > 其它

Flex & GNU Bison 简单四则混合运算

2009-10-20 10:26 267 查看
用 Flex 和 GNU Bison 实现的非常简单的计算器,支持 int 和 double 类型的 +-*/% 运算以及括号 ()

main.l

%{
#include <math.h>
#include "main.tab.h"
void yyerror(const char *);
%}
integer [0-9]+
fraction "."{integer}
exponent [eE][+-]?{integer}
pointfloat {integer}?{fraction}|{integer}"."
exponentfloat ({integer}|{pointfloat})exponent
real {pointfloat}|{exponentfloat}
%%
{integer} {yylval.integer = atoi(yytext); return INTEGER; }
{real} {yylval.real = atof(yytext); return REAL; }
[-()+*/%/n] {return *yytext; }
[ /t] ;
. {yyerror("error: unknown character/n"); }
%%
int yywrap(void)
{
return 1;
} 


main.y

%{
#include <math.h>
#include <stdio.h>
void yyerror(const char *);
int yylex(void);
%}
%union{int integer; double real; };
%token <integer> INTEGER
%token <real> REAL
%type <integer> iexpr
%type <real> rexpr
%left UMINUS
%left '+' '-'
%left '*' '/' '%'
%%
lines: lines expr '/n'
| lines '/n'
|
;
expr: iexpr {printf("%d/n", $1); }
| rexpr {printf("%lg/n", $1); }
iexpr: INTEGER
| '-' iexpr %prec UMINUS {$$ = -$2; }
| iexpr '+' iexpr {$$ = $1 + $3; }
| iexpr '-' iexpr {$$ = $1 - $3; }
| iexpr '*' iexpr {$$ = $1 * $3; }
| iexpr '/' iexpr {$$ = $1 / $3; }
| iexpr '%' iexpr {$$ = $1 % $3; }
| '(' iexpr ')' {$$ = $2; }
;
rexpr: REAL
| '-' rexpr %prec UMINUS {$$ = -$2; }
| rexpr '+' rexpr {$$ = $1 + $3; }
| rexpr '-' rexpr {$$ = $1 - $3; }
| rexpr '*' rexpr {$$ = $1 * $3; }
| rexpr '/' rexpr {$$ = $1 / $3; }
| rexpr '%' rexpr {$$ = fmod($1, $3); }
| '(' rexpr ')' {$$ = $2; }
| rexpr '+' iexpr {$$ = $1 + $3; }
| rexpr '-' iexpr {$$ = $1 - $3; }
| rexpr '*' iexpr {$$ = $1 * $3; }
| rexpr '/' iexpr {$$ = $1 / $3; }
| rexpr '%' iexpr {$$ = fmod($1, $3); }
| iexpr '+' rexpr {$$ = $1 + $3; }
| iexpr '-' rexpr {$$ = $1 - $3; }
| iexpr '*' rexpr {$$ = $1 * $3; }
| iexpr '/' rexpr {$$ = $1 / $3; }
| iexpr '%' rexpr {$$ = fmod($1, $3); }
%%
void yyerror(const char *s)
{
fputs(s, stdout);
}
int main(void)
{
yyparse();
return 0;
} 


Makefile(请把下划线替换为空格)

CC = gcc
CCFLAGS = -lm
RM = rm -f
BIN = main
OBJS = lex.yy.o $(BIN).tab.o
$(BIN): $(OBJS)
${CC} -o $(BIN) $(CCFLAGS) $(OBJS)
$(BIN).tab.h $(BIN).tab.c: $(BIN).y
bison -d $(BIN).y
lex.yy.c: $(BIN).l $(BIN).tab.h
flex $(BIN).l
.PHONY: clean
clean:
$(RM) $(OBJS) $(BIN) *.c *.h


-----

编译运行

make

./main

-----

(1+4)%(4-1)+5.1

7.1

9-(9-(9-(9-9)))

9

.1

0.1

&

error: unknown character
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息