我正在尝试使用带有可变重复因子的 Boost Spirit X3 指令重复。基本思想是标头+有效负载,其中标头指定有效负载的大小。一个简单的示例“3 1 2 3”被解释为 header = 3, data= {1, 2, 3} (3 个整数)。
我只能从灵气文档中找到例子。它使用 boost phoenix reference 来包装变量因子: http: //www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html
std::string str;
int n;
test_parser_attr("\x0bHello World",
char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl; // will print "11,Hello World"
我为精神 x3 写了以下简单的例子,没有运气:
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;
int main( int argc, char **argv )
{
string data("3 1 2 3");
string::iterator begin = data.begin();
string::iterator end = data.end();
unsigned int n = 0;
auto f = [&n]( auto &ctx ) { n = x3::_attr(ctx); };
bool r = phrase_parse( begin, end, uint_[f] >> repeat(boost::phoenix::ref(n))[int_], space );
if ( r && begin == end )
cout << "Parse success!" << endl;
else
cout << "Parse failed, remaining: " << string(begin,end) << endl;
return 0;
}
使用 boost 1.59.0 和 clang++ (flags: -std=c++14) 编译上面的代码会得到以下结果:
boost_1_59_0/boost/spirit/home/x3/directive/repeat.hpp:72:47: error: no matching constructor for
initialization of 'proto_child0' (aka 'boost::reference_wrapper<unsigned int>')
typename RepeatCountLimit::type i{};
如果我硬编码repeat(3)
而不是repeat(boost::phoenix::ref(n))
它可以正常工作,但这不是一个可能的解决方案,因为它应该支持可变重复因子。
编译repeat(n)
成功完成,但解析失败,输出如下:
“Parse failed, remaining: 1 2 3"
查看源代码,它调用模板类型变量boost/spirit/home/x3/directive/repeat.hpp:72
的空构造函数,然后在 for 循环期间分配,迭代 min 和 max。然而,由于类型是一个引用,它应该在构造函数中初始化,所以编译失败。查看之前库版本 boost/spirit/home/qi/directive/repeat.hpp:162 的等效源代码,它是直接分配的:RepeatCountLimit::type
i
typename LoopIter::type i = iter.start();
我不确定我在这里做错了什么,或者 x3 当前是否不支持可变重复因子。我将不胜感激解决此问题的一些帮助。谢谢你。