今天在讀《編譯原理及實踐》時,看到了一個簡單的整數計算器的實現。
按照書上的思路,我稍微進行了擴展:
1、從整數計算器擴展到小數計算器。
2、支持除法
3、支持空字符。
運行效果如下:
代碼很簡單,如下:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+Y2FsLmM6PC9wPgo8cD48cHJlIGNsYXNzPQ=="brush:java;">#include
#include
char token;
double exp(void);
double term(void);
double factor(void);
char getPrintableChar(void);
void match(char expectedToken);
void error(void);
int main(void)
{
double result;
for (;;)
{
token = getPrintableChar();
if (token == 'q')
break;
result = exp();
if (token == '\n')
printf("Result is: %g\n", result);
else
error();
}
return 0;
}
double exp(void)
{
double temp = term();
while (token == '+' || token == '-')
switch(token)
{
case '+': match('+');
temp += term();
break;
case '-': match('-');
temp -= term();
break;
}
return temp;
}
double term(void)
{
double temp = factor();
while (token == '*' || token == '/')
switch(token)
{
case '*': match('*');
temp *= factor();
break;
case '/': match('/');
temp /= factor();
break;
}
return temp;
}
double factor(void)
{
double temp;
if (token == '(')
{
match('(');
temp = exp();
match(')');
} else if (isdigit(token))
{
ungetc(token, stdin);
scanf("%lf", &temp);
token = getPrintableChar();
} else
error();
return temp;
}
void error(void)
{
fprintf(stderr, "Error!\n");
exit(EXIT_FAILURE);
}
void match(char expectedToken)
{
if (expectedToken == token)
token = getPrintableChar();
else
error();
}
char getPrintableChar(void)
{
char temp;
do
temp = getchar();
while (isblank(temp));
return temp;
}
程序實現的思路是按照EBNF規則實現,即:
-> { }
-> + | -
-> { }
-> * | /
-> ( ) | Number
關於EBNF, 可以參考書上的內容,在這裡就不贅述了。