将解析器分配给自动变量

时间:2014-02-25 19:06:15

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

灵魂解析器是不是要与auto一起使用?

简单的解析器在传递给qi::parse()内联时工作正常,但如果通过auto变量传递则崩溃为segfault:

#include <cstdio>
#include <string>
#include <boost/spirit/include/qi.hpp>

using namespace std;

namespace qi = boost::spirit::qi;

int main()
{
    string line = "[z]";

    auto bracketed_z = '[' >> +qi::char_('z') >> ']';

    auto p = line.cbegin();
    printf("%d", qi::parse(p, line.cend(), '[' >> +qi::char_('z') >> ']'));  // Works

    p = line.cbegin();
    printf("%d", qi::parse(p, line.cend(), bracketed_z));                    // Crashes
}

使用g ++ - 4.8和VC13重新编译。

更新:原始代码中修复了错误(p在第二次调用parse()之前未重新初始化。

2 个答案:

答案 0 :(得分:10)

Spirit Parsers不适用于Spirit V2中的auto

这是因为底层的Proto表达式模板包含对临时表的引用。

您可以使用

  • qi::copy()(在boost_1_55_0之后存在于主干中,此时尚未发布任何版本)
  • boost::proto::deep_copy
  • 或BOOST_SPIRIT_AUTO(第一次创造here

我在SO https://stackoverflow.com/search?q=user%3A85371+deep_copy上经常写这些事情,具体来说,这是:

Boost Spirit X3不会有此限制。

答案 1 :(得分:3)

Boost.Spirit使用表达式模板,但不适用于auto。解决方法是使用boost::proto::deep_copy

auto bracketed_z = proto::deep_copy('[' >> +qi::char_('z') >> ']');