融合适应结构中的 Boost spirit x3 元组成员

Boost spirit x3 tuple member in fusion-adapted struct

以下测试用例是一个更大的多文件解析器的缩减,因此声明和定义的顺序有点奇怪。它不编译,我的理解是 std::tuple 绊倒了它。从文档来看,在我看来,如果存在正确的包含,则合成属性应该有一个 std::tuple 。我做错了什么?

// -*- mode: c++; -*-

#include <iostream>
#include <tuple>

#include <boost/fusion/include/io.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_tuple.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>

#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;

#include <boost/spirit/include/support_istream_iterator.hpp>

namespace ast {

struct S {
    std::tuple< int, int > t;
    int i;
};

using boost::fusion::operator<<;

} // namespace ast

BOOST_FUSION_ADAPT_STRUCT (ast::S, t, i)

namespace parser {

using S_type = x3::rule< struct S_class, ast::S >;
BOOST_SPIRIT_DECLARE(S_type)

struct S_class;
const S_type S = "S";

using x3::int_;
const auto S_def = ( int_ >> int_ ) >> int_;

BOOST_SPIRIT_DEFINE(S)

struct S_class { };

} // namespace parser

template< typename Iterator >
bool parse (Iterator& iter, Iterator last, ast::S& s) {
    using x3::ascii::space;

#if 1
    return x3::phrase_parse (iter, last, parser::S, space, s);
#else
    return x3::parse (iter, last, ( x3::int_ >> x3::int_ ) >> x3::int_, s);
#endif // 0
}

int main () {
    const std::string s = "1 2 3";
    auto iter = s.begin ();

    ast::S obj;
    return !parse (iter, s.end (), obj);
}

非常感谢。

这是一个嵌套结构。但是,您解析为与 AST 结构不匹配的平面合成元组:

换句话说,((int, int), int) 在结构上与 (int, (int, int)) 甚至 (int, int, int) 不兼容,因为您的规则将解析。

上述解决方法有助于属性强制转换以反映所需(和必需)的结构。