【问题标题】:Assigning parsers to auto variables将解析器分配给自动变量
【发布时间】:2014-02-25 19:06:15
【问题描述】:

精神解析器不应该与auto一起使用吗?

一个简单的解析器在传递给qi::parse() inline 时可以正常工作,但如果通过auto 变量传递,则会因段错误而崩溃:

#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() 之前没有重新初始化)。

【问题讨论】:

  • 任何 c++ 解析器如何处理auto?解析器旨在读取在运行时确定的特定类型,auto 类型在编译时解析。所以恕我直言,除非auto 导致boost::variantboost::any 这是不可能的。
  • 请注意,第一个迭代器是通过引用 (IIRC) 传递的。也就是说,p 在第一次调用qi::parse 之后已经改变了。
  • 谢谢你,@dyp。修复了错误。
  • @πάνταῥεῖ:在这个简单的例子中,一切都应该是编译时的。

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


【解决方案1】:

Spirit 解析器不适用于 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 没有这个限制。

【讨论】:

  • 最近的错误太频繁了。因此需要有当代版本的 Boost.Spirit Qi 库,它必须完全启用 C++11/C++1y(我认为它至少应该包含对移动语义的支持)。
  • @Dukales 这似乎是一个需要引用的观点 :) 如果你的意思是你渴望看到 Spirit X3,+1
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多