荣誉版主
- 积分
- -2403
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2010-5-4
- 最后登录
- 1970-1-1
|
回复 wwwyhx
对,上面15楼提到这个问题,后来也提到通过加参数来解决。
隔了这么长时间回头之前的代码还是有很多不理想的地方。现在稍做改动再贴一下,不知还有没有别的问题,供参考。
darksteel 发表于 2012-4-11 07:15 ![]()
其实是编译原理的一个递归下降语法分析, 可以用在稍稍复杂的情况, 列出语法规则直接写程序, 左结合不需要参数可以用迭代的办法实现,比如下面这个:
- //implement like a+b*(2-c)
- //Top down parser, the correct expression is the first step
- //add = mul [+ or - mul]*
- //mul = factor [* or / factor]*
- //factor = numeric or (add) or (+ or - factor)
- //notice: use reference for all parameter
- int add(const char*& p);
- int mul(const char*& p);
- int factor(const char*& p);
- int numeric(const char*& p);
- void skipblank(const char*& p)
- {
- while (*p == ' ')
- p++;
- }
- int add(const char*& p)
- {
- skipblank(p);
- int nRet = mul(p);
- skipblank(p);
- while (*p == '+' || *p == '-')
- {
- if (*p == '+')
- nRet += mul(++p); //should be ++p not p++, otherwise, compile error
- else nRet -= mul(++p);
- skipblank(p);
- }
- return nRet;
- }
- int mul(const char*& p)
- {
- skipblank(p);
- int nRet = factor(p);
- skipblank(p);
- //you can't use recursion like "* or / mul" here, if will calculate from the right.
- //E.g consider 2*3/4, if recursive method like "* or / mul" is used, it will calculate
- //"3/4" first which result is 0, and then calculate 2*0 == 0. However, it should be
- //2*3 first == 6 and then 6/4 which is 1
- while (*p == '*' || *p == '/')
- {
- if (*p == '*')
- nRet *= factor(++p);
- else nRet /= factor(++p);
- skipblank(p);
- }
- return nRet;
- }
- int factor(const char*& p)
- {
- skipblank(p);
- int nRet = 0;
- if (*p == '(')
- {
- p++;
- nRet = add(p);
- skipblank(p);
- if (*p == ')')
- p++;
- }
- else if (*p == '+' || *p == '-')
- {
- bool bNeg = *p == '-';
- p++;
- nRet = factor(p);
- if (bNeg) nRet = -nRet;
- }
- else
- nRet = numeric(p);
- return nRet;
- }
- int numeric(const char*& p)
- {
- skipblank(p);
- int nRet = 0;
- while (*p >= '0' && *p <= '9')
- {
- nRet = (*p - '0') + nRet * 10;
- p++;
- }
- return nRet;
- }
复制代码 |
|