我有一个工作解析器来读取棋盘游戏的位置描述(国际选秀,官方语法):
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
auto const colon = x3::lit(':');
auto const comma = x3::lit(',');
auto const dash = x3::lit('-');
auto const dot = x3::lit('.');
auto const king = x3::char_('K');
auto const color = x3::char_("BW");
auto const num_sq = x3::int_;
auto const num_pc = -king >> num_sq; // Kxx means king on square xx, xx a man on that square
auto const num_rng = num_pc >> dash >> num_sq; // xx-yy means range of squares xx through yy (inclusive)
auto const num_seq = (num_rng | num_pc) % comma; // <--- attribute should be std::vector<boost::variant>
auto const ccn = colon >> color >> -num_seq;
auto const num_not = x3::repeat(2)[ccn]; // need to specify both white and black pieces
auto const fen = color >> num_not >> -dot;
现在我想从合成属性中提取值,所以我围绕 Boost.Fusion 等做了样板舞,
namespace ast {
struct num_pc { boost::optional<char> k; int sq; };
struct num_rng { boost::optional<char> k; int first, last; };
using rng_or_pc = boost::variant<num_rng, num_pc>;
struct num_seq { std::vector<rng_or_pc> sqrs; };
struct ccn { char c; boost::optional<num_seq> seq; };
struct num_not { std::vector<ccn> n; };
struct fen { char c; num_not n; };
} // namespace ast
BOOST_FUSION_ADAPT_STRUCT(ast::num_pc, (boost::optional<char>, k), (int, sq))
BOOST_FUSION_ADAPT_STRUCT(ast::num_rng, (boost::optional<char>, k), (int, first), (int, last))
BOOST_FUSION_ADAPT_STRUCT(ast::num_seq, (std::vector<ast::rng_or_pc>, sqrs))
BOOST_FUSION_ADAPT_STRUCT(ast::ccn, (char, c), (boost::optional<ast::num_seq>, seq))
BOOST_FUSION_ADAPT_STRUCT(ast::num_not, (std::vector<ast::ccn>, n))
BOOST_FUSION_ADAPT_STRUCT(ast::fen, (char, c), (ast::num_not, n))
x3::rule<class num_pc_class, ast::num_pc > num_pc = "num_pc";
x3::rule<class num_rng_class, ast::num_rng> num_rng = "num_rng";
x3::rule<class num_seq_class, ast::num_seq> num_seq = "num_seq";
x3::rule<class ccn_class, ast::ccn > ccn = "ccn";
x3::rule<class num_not_class, ast::num_not> num_not = "num_not";
x3::rule<class fen_class, ast::fen > fen = "fen";
auto const colon = x3::lit(':');
auto const comma = x3::lit(',');
auto const dash = x3::lit('-');
auto const dot = x3::lit('.');
auto const king = x3::char_('K');
auto const color = x3::char_("BW");
auto const num_sq = x3::int_;
auto const num_pc_def = -king >> num_sq;
auto const num_rng_def = num_pc >> dash >> num_sq;
auto const num_seq_def = (num_rng | num_pc) % comma;
auto const ccn_def = colon >> color >> -num_seq;
auto const num_not_def = x3::repeat(2)[ccn];
auto const fen_def = color >> num_not >> -dot;
BOOST_SPIRIT_DEFINE(num_pc, num_rng, num_seq, ccn, num_not, fen)
但是,然后我收到一条错误消息
错误:static_assert 失败“属性没有预期的大小。”
和几页下来:
^ main.cpp:16:8: 注意:候选构造函数(隐式移动构造函数)不可行:第一个参数 struct num_seq { sqrs;没有从 '
std::vector<boost::variant<ast::num_rng, ast::num_pc>, std::allocator<boost::variant<ast::num_rng, ast::num_pc> > >
' 到 'ast::num_seq' 的 已知转换std::vector<rng_or_pc>
};^ main.cpp:16:8: 注意:候选构造函数(隐式复制构造函数)不可行:第一个参数 struct num_seq { sqrs;没有从 '
std::vector<boost::variant<ast::num_rng, ast::num_pc>, std::allocator<boost::variant<ast::num_rng, ast::num_pc> > >
' 到 'const ast::num_seq' 的 已知转换std::vector<rng_or_pc>
};
问题:此错误来自哪里,如何解决?显然我的规则的综合属性num_seq
不等于std::vector<boost::variant>>
. 我该如何纠正?