编译原理-基于WINDOWS下FLEX与BISON的计算器实现

要求

基于词法分析程序自动构造工具Flex与语法分析程序自动构造工具Bison,编制简单的计算器程序。

 

参考示例程序, 用Flex和Bison实现一个功能更为强大的计算器,尽可能多的包含以下运算(支持浮点数):

a) 加、减、乘、除运算

b) 乘方power、开方sqrt运算

c) 位运算  – 与、或、非...(不做)

d) 三角函数运算 – sin、cos...

e) 求阶乘

f) 求模(不做)

g) 求log以e为底的对数(不做)

h) 求log以10为底的对数

测试样例

52+ 21*2 - 2.1

91.9

 

(25*2+3)*(1-25)

-1272

 

pow(4,2)+sqrt(144)

28

 

sin(30)*cos(60)

0.25

 

log(100)+3!

8

 

具体实现

具体步骤见https://blog.csdn.net/artherlex/article/details/103455632

下面是calc.l和calc.y的具体实现

calc.l

%{
	#include "calc.tab.h"
	#define YYSTYPE double
	#include <stdlib.h>
	void yyerror(char*);

%}

%% 

(0(\.[0-9]+)?)|([1-9][0-9]*(\.[0-9]+)?)    { yylval = atof(yytext); return NUMBER; }

[-+()=/*!,\n] {
    return *yytext;
}

"sin" {return SIN;}

"cos" {return COS;}

"tan" {return TAN;}

"pow" {return POW;}

"sqrt" {return SQRT;}

"log" {return LOG;}


"//".* 

[ \t]   { /* ignore white space */ }

.      {}

%%
int yywrap()
{return 1;}

calc.y

%token   NUMBER SIN COS TAN LOG SQRT POW
%left    '+' '-'
%left    '*' '/'
%left    '!'
%left    ','
%{
	#include <stdio.h>
    #include <math.h>
	#define YYSTYPE double
    #define pi 3.1415926
    
    int yylex();
	void yyerror(char*);
%}


%%

program:
    program statement '\n'
    |
    ;
	
statement:
     expr    {printf("%g\n",$1);}
	 |
     ;
	 
expr:
	NUMBER
    |expr '+' expr    {$$ = $1 + $3;}
    |expr '-' expr    {$$ = $1 - $3;}
    |expr '*' expr    {$$ = $1 * $3;}
    |expr '/' expr    {$$ = $1 / $3;}
    |expr '!'         {int i=1,s=1;for(;i<=$1;i++){s*=i;}$$=s;}
    |'('expr')'       {$$ = $2;}
    |LOG'('expr')'    { $$ = log10($3); }
    |POW '('expr','expr')' { $$ = pow($3,$5); }
    |SQRT '('expr')'     { $$ = sqrt($3); }
    |SIN'('expr')'       {$$ = sin($3*pi/180.0);}
    |COS'('expr')'       {$$ = cos($3*pi/180.0);}
    |TAN'('expr')'       {$$ = tan($3*pi/180.0);}
    ;
 
%%
int main()

{

  yyparse();

  return 0;
}

 

yyerror(char *s)

{

  fprintf(stderr, "error: %s\n", s);

}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值