布尔函数递归检查表达式的有效性?

时间:2012-02-13 02:01:24

标签: c++ parsing recursion boolean

我想创建一种形式的解析器:

#include <iostream>
#include <string>
#include <sstream>
#include <cctype>

using namespace std;

bool isValid(istringstream& is)
{
  char ch;
  is.get(ch); //I know get(ch) is a good start but this is as for as I got :)
  .......
  ....
}

int main()
{
  string s;
  while(getline(cin,s))
  {
    istringstream is(s);
    cout<<(isValid(is)? "Expression OK" : "Not OK")<<endl;
  }
}

布尔函数,如果 char 的序列的格式为&#34; 5&#34;则返回TRUE。或&#34;(5 + 3)&#34;或&#34;((5 + 3)+6)&#34;或&#34;(((4 + 2)+1)+6)&#34; ......等等,对任何其他案件都是假的

基本上,如果表达式是单个数字或形式为&#34;打开括号 - 单个数字加号 - 单个数字 - 关闭括号&#34;

,则表达式将被视为有效。
  • 有效表达式= 单个数字

  • 有效表达式=(有效表达式 + 有效表达式

鉴于上述形式的大小没有限制(开括号和右括号的数量等等),我希望使用递归来做到这一点

成为我的新手..感谢您提供任何有用的信息!

1 个答案:

答案 0 :(得分:0)

要做一个递归解决方案,你首先想要将字符串读入缓冲区,然后执行以下操作:

int expression(char* str) {
    if (*str == '(') {
        int e1 = expression(str + 1);
        if (e1 == -1 || *(str + 1 + e) != '+') {
            return -1;
        }
        int e2 = expression(str + 1 + e + 1);
        if (e2 == -1 || *(str + 1 + e + 1 + e2) != ')') {
            return -1;
        }
        return 1 + e1 + 1 + e2 + 1;
    }

    if (*str >= '0' || *str <= '9') {
        return 1;
    }

    return -1;
}

bool isvalid(char* str) {
    int e1 = expression(str);
    if (e1 < 0) {
        return false;
    }
    if (e1 == strlen(str)) {
        return true;
    }
    if (*(str + e1) != '+') {
        return false;
    }
    int e2 = expression(str + e1 + 1);
    if (e2 < 0) {
        return false;
    }
    return (e1 + 1 + e2 == strlen(str));
}

基本上,表达式函数在其参数处返回有效表达式的长度。如果它的参数以括号开头,则在此之后获取表达式的长度,在此之后验证加号,然后在下一个表达式之后验证右括号。如果参数以数字开头,则返回1.如果某些内容搞砸了,则返回-1。然后使用该函数,我们可以通过一些总和和字符串的长度来判断字符串是否有效。

我根本没有测试过这个函数,但是我可以想到的唯一可能失败的情况就是括号过多:((5))。

递归的替代方法可能是某种词法解析,例如:

enum {
    ExpectingLeftExpression,
    ExpectingRightExpression,
    ExpectingPlus,
    ExpectingEnd,
} ParseState;

// returns true if str is valid
bool check(char* str) {
    ParseState state = ExpectingLeftExpression;

    do {
        switch (state) {
            case ExpectingLeftExpression:
                if (*str == '(') {
                } else if (*str >= '0' && *str <= '9') {
                    state = ExpectingPlus;
                } else {
                    printf("Error: Expected left hand expression.");
                    return false;
                }
            break;
            case ExpectingPlus:
                if (*str == '+') {
                    state = ExpectingRightExpression;
                } else {
                    printf("Error: Expected plus.");
                    return false;
                }
            break;
            case ExpectingRightExpression:
                if (*str == '(') {
                    state = ExpectingLeftExpression;
                } else if (*str >= '0' && *str <= '9') {
                    state = ExpectingEnd;
                } else {
                    printf("Error: Expected right hand expression.");
                    return false;
                }
            break;
        }
    } while (*(++str));

    return true;
}

该功能根本不完整,但您应该能够看到它的发展方向。我认为在这种情况下递归效果更好。