今天在读《编译原理及实践》时,看到了一个简单的整数计算器的实现。
按照书上的思路,我稍微进行了扩展:
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);elseerror();}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();} elseerror();return temp;
}void error(void)
{fprintf(stderr, "Error!\n");exit(EXIT_FAILURE);
}void match(char expectedToken)
{if (expectedToken == token)token = getPrintableChar();elseerror();
}char getPrintableChar(void)
{char temp;dotemp = getchar();while (isblank(temp));return temp;
}
程序实现的思路是按照EBNF规则实现,即:
<exp> -> <term> { <addop> <term> }
<addop> -> + | -
<term> -> <factor> { <mulop> <factor> }
<mulop> -> * | /
<factor> -> ( <exp> ) | Number
关于EBNF, 可以参考书上的内容,在这里就不赘述了。














![[已授权] 互联网定位技术小谈](http://xianzhi.aliyun.com/forum/attachment/Mon_1703/14_1150978582736040_635685898d3bfc6.jpg)

