【问题标题】:Understanding Boost.spirit's string parser理解 Boost.spirit 的字符串解析器
【发布时间】:2014-03-24 10:24:45
【问题描述】:
#include <iostream>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
int main ()
{
    using qi::string;

    std::string input("a");
    std::string::iterator strbegin = input.begin();
    std::string p;
    bool ok = qi::phrase_parse(strbegin, input.end(),
            ((string("a")  >> string("a")) | string("a")),
            qi::space,                  
            p);                               

    if (ok && strbegin == input.end()) {
        std::cout << p << std::endl;
        std::cout << p.size() << std::endl;
    } else {
        std::cout << "fail" << std::endl;
        std::cout << std::string(strbegin, input.end()) << std::endl;
    }
}

这个程序输出aa。这怎么可能?输入字符串为a。解析器应匹配 aaa。我写了string("a") 只是为了测试操作员。

使用char_而不是string时也是如此。

【问题讨论】:

标签: c++ parsing boost boost-spirit boost-spirit-qi


【解决方案1】:

它本身不是字符串匹配器。它是 [属性传播] + [回溯] 在行动。

字符串属性是一个容器属性,许多元素可以通过不同的解析器子表达式分配给它。现在出于效率原因,Spirit 不会在回溯时回滚发射属性的值。

通常这根本没有问题,但正如您所见,替代方案的第一个失败分支中的“a”仍然存在。

改写或使用“大枪”qi::hold[] 指令:

(qi::hold [ string("a")  >> string("a") ] | string("a")),

改写如下:

qi::string("a") >> -qi::string("a"),

另外,如果您真的只是想匹配某些文本字符串,请考虑:

(qi::raw [ qi::lit("aa") | "a" ]), 
// or even just
qi::string("aa") | qi::string("a"),

现在哪一个最适用,取决于你的语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2016-02-22
    相关资源
    最近更新 更多