コンパイル原理-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
calc.y
文法解析プログラム自動構築ツール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);
}