Cで計算機を作る(乗算、除算)
―準備中―
C言語で計算機を作ってみます。前回はは足し算、引き算だけの基本形からやってみました。
→「Cで計算機を作る(足し算、引き算)」
今回は乗算(掛け算)、除算(割り算)、カッコ( )を使えるようにしてみます。
プログラムはVB.netで作ったプログラムをC用に改変したものなので、
プログラムの説明は「VB.netで計算機を作る(乗算、除算)」をご参照下さい。
今回は、前回「Cで計算機を作る(足し算、引き算)」から変更のあった点のみ説明を書きます。
主要な変更・追加点は、以下の2つです。
・乗算・除算を処理するための関数として、termという関数を追加し
演算のための基本的な関数はexpression, term, primary_expression, get_tokenの4つにします。
・括弧( )の処理は、primary_expressionの中で行い、expressionを再帰的に呼び出すことで
実装します。
以下、変更箇所の説明です。
@expression()関数では乗算、除算処理のため
primary_expressionを呼び出していたのをtermをコールするように変更します。
(A) v1=primary_expression(); => v1=term();
同様に(B) v2 = term(); に変更
double expression() {
double v1, v2;
token t;
v1=term(); /* (A) */
printf("expession v1:%lf\n",v1);
while (1){
get_token(&t);
printf("expression %s: %d : %d\n", t.str, t.type, t.v);
if (t.type != add_op && t.type != sub_op) { unget_token(); break;}
v2 = term(); /* (B) */
printf("expression v2:%lf\n", v2);
if (t.type == add_op) v1 = v1 + v2;
if (t.type == sub_op) v1 = v1 - v2;
printf("expression calculated v1:%lf\n", v1);
}
return (v1);
}A乗算、除算を処理するための関数term()を追加
double term() {
double v1, v2;
token t;
v1=primary_expression();
printf("term v1:%lf\n",v1);
while (1){
get_token(&t);
printf("term %s: %d : %d\n", t.str, t.type, t.v);
if (t.type != mul_op && t.type != div_op) { unget_token(); break;}
v2 = primary_expression();
printf("term v2:%lf\n", v2);
if (t.type == mul_op) v1 = v1 * v2;
if (t.type == div_op) v1 = v1 / v2;
printf("term calculated v1:%lf\n", v1);
}
return (v1);
}
Bprimary_exptression()関数では
(c) のif文で括弧( )の処理の追加
左括弧"(" (type.lparen)が来たら、関数expressionを再帰的に呼び出す。
( ) 内の処理が終わるとexpressionからの戻り値をvに保存し、次のtokenで右括弧")" (type.rparen)が来たら
vをreturnする。
double primary_expression() {
token t;
double v;
get_token(&t);
printf("primary_expression %s: %d : %d \n", t.str, t.type, t.v);
if (t.type == number) return (t.v);
/* (C) */ if (t.type == lparen)
{v=expression(); get_token(&t);
if (t.type==rparen) {return(v);} else printf("raparen is missing");}
else return (0);
}
Cunget_token()関数で
unget=1 というフラグを立てる。
これによりget_token()関数内でもungetのフラグが経っているときの処理を追加
void get_token(token *t) {
static int i = 0;
if (unget == 1) {i=i-1; unget=0;}
printf("get_token %d: %s : %d : %d \n", i, tok[i].str, tok[i].type, tok[i].v);
/* Assign the structure *t=toku[i] */
*t=tok[i];
i++;
}
void unget_token() {
unget=1;
}