コンパイル原理-WINDOWS下FLEXとBISONに基づく計算機実現

2530 ワード

要求
文法解析プログラム自動構築ツールFlexと文法解析プログラム自動構築ツールBisonに基づいて,簡単な計算機プログラムを作成する.
 
サンプルプログラムを参照して、FlexとBisonでより強力な計算機を実現し、以下の演算(浮動小数点数をサポート)をできるだけ多く含みます.
a)加算、減算、乗算、除算
b)乗方パワー、開方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 
	void yyerror(char*);

%}

%% 

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

[-+()=/*!,
] { 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 
    #include 
	#define YYSTYPE double
    #define pi 3.1415926
    
    int yylex();
	void yyerror(char*);
%}


%%

program:
    program statement '
' | ; statement: expr {printf("%g
",$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
", s); }