今天在读《编译原理及实践》时,看到了一个简单的整数计算器的实现。
按照书上的思路,我稍微进行了扩展:
1、从整数计算器扩展到小数计算器。
2、支持除法
3、支持空字符。
运行效果如下:

代码很简单,如下:
cal.c:
#include <stdio.h>
#include <stdlib.h>
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规则实现,即:
<exp> -> <term> { <addop> <term> }
<addop> -> + | -
<term> -> <factor> { <mulop> <factor> }
<mulop> -> * | /
<factor> -> ( <exp> ) | Number
关于EBNF, 可以参考书上的内容,在这里就不赘述了。 |