如何解析结构化格式?

时间:2011-12-25 19:27:34

标签: c++ parsing stl token

我有一个字符串,我想在结构块上解析它。

所以,像这样的字符串结构:

if(true) {
    if(true) {
        if(true) {}
    }
}
if(true) {
    if(true) {
        if(true) {}
    }
}

我想在父块上拆分一个:

if(true) {
    if(true) {
        if(true) {}
    }
},

if(true) {
    if(true) {
        if(true) {}
    }
}

我的代码:

string condition = 
"if(true) {\
    if(true) {\
        if(true) {}\
    }\
}\
if(true) {\
    if(true) {\
        if(true) {}\
    }\
}";

string item; 
stringstream stream(condition);
vector<string> array;

//splitting on sections
while (getline(stream, item, '}')) {
    array.push_back(item + "}");
}

for(int i = 0; i < array.size(); i++) {
    cout << i << array[i] << endl;
}

结果:

0 if(true) { if(true) { if(true) {}
1   }
2 }
3 if(true) { if(true) { if(true) {}
4   }
5 }

但需要:

0 if(true) { if(true) { if(true) {} } }
1 if(true) { if(true) { if(true) {} } }

如何更正确地检测和解析父块或告诉算法?

1 个答案:

答案 0 :(得分:2)

您需要保持当前深度的计数。我发现最好的解析器是基于迭代器的,所以这就是我在这里展示的内容。除了最简单的格式外,std::getline对解析不是很有用。

完全未经测试的代码:

std::vector<std::string> vec;

int depth = 0;
std::string::const_iterator first = condition.begin(),
                            last = condition.end(),
                            iter = first;

for(;;)
{
    iter = std::find_if(iter, last,
                        [](char ch) { return ch == '{' || ch == '}'; });

    if(iter == last)
    {
        if(depth)
        {
            throw std::runtime_error("unclosed block found.");
        }

        break;
    }

    if(*iter == '{')
    {
        ++depth;
        ++iter;
    }
    else if(*iter == '}' && !--depth)
    {
        v.push_back(std::string(first, ++iter));
        first = iter;
    }
    else
    {
        ++iter;
    }
}