bison,flexによる電卓作成
解決したいこと
大学の講義でコンパイラについて学んでおり,bison,flexを用いて電卓プログラムを作成する演習がありました.現在,一つの式は解析できるようになったのですが,複数式は打ち込めません.講義ではヒントとして,「再帰的な規則を使って,複数の式が計算できるようにすること」とありました.どのようにコードを書けばよいのでしょうか.
発生している問題・エラー
該当するソースコード
/* 数式の計算 */
%token NUM /* トークンの定義 */
%{
int yylex(void);
void yyerror(const char *s);
int printf(const char *format, ...);
int getchar(void);
int TAB=0x09; /* タブ */
%}
%%
line : expr '\n' { printf("%d\n", $1); }
| line expr '\n' { printf("%d\n", $1); }
;
expr : expr '+' term { $$=$1+$3; }
| expr '-' term { $$=$1-$3; }
| term
;
term : term '*' factor { $$=$1*$3; }
| term '/' factor { if($3 == 0){
printf("error:devision by zero\n");
} /* (d)0による除算はエラー */
else $$=$1/$3; }
| term '%' factor { if($3 == 0){
printf("error:devision by zero\n");
} /* (d)0による除算はエラー */
else $$=$1%$3; } /* (a)剰余演算子%の追加 */
| factor
;
factor : '(' expr ')' { $$=$2; }
| '-' NUM { $$=-$2; } /* (c)負の数を使えるように */
| NUM
;
%%
#include <stdio.h>
#include <ctype.h>
/* getchar() : 1文字ずつ,文字もしくは数字を変数に代入できる関数 */
/* ungetc(int c, FILE *stream)
: 後の操作で読み込めるように,cをunsigned char型にキャストして,
streamに返す. */
/* isdight(int c): cが数字の場合真(0以外の値),それ以外の場合偽(0)を返す */
char c_exc[] = { '\n','%','(',')','*','+','-','/' };
int check_exc(const char* array, int size,const int c) {
for (int i = 0; i < size; ++i) {
if (c == array[i]) {
return 1;
}
}
return 0;
}
int yylex() /* 字句解析関数 */
{
int c;
while ((c = getchar()) == ' ' || (c == TAB)); /* (b)空白,タブを読み飛ばす */
if (isdigit(c)){ /* 数字の処理 */
yylval = c - '0'; /* 0のASCIIコード:0x30 */
while (isdigit(c = getchar())){ /* 数字列をint型の値へ */
yylval = yylval * 10 + (c-'0');
}
ungetc(c, stdin); /* 入力の文字を元に戻す */
return NUM;
}
else{
if(check_exc(c_exc,(sizeof c_exc)/(sizeof c_exc[0]),c)==0) {
printf("error:exceptional word \"%c\"\n",c); /* 空白,タブ,改行,数字以外の文字はエラー */
yylex();
}
else return c;
}
}
0