c++ - 20多种变体的Boost Spirit如何使用?

标签 c++ boost-spirit boost-mpl

我正在使用 Boost Spirit 解析一个相当复杂的语法,并且遇到了一个具有 20 多种类型(此处为 21 种)的变体的问题:

namespace eddic { namespace ast {

typedef boost::mpl::vector<
            Integer,
            IntegerSuffix,
            Float,
            Litteral,
            VariableValue,
            DereferenceValue,
            Expression,
            Unary,
            Null,
            True,
            False,
            ArrayValue,
            FunctionCall,
            MemberFunctionCall,
            Cast,
            BuiltinOperator,
            Assignment,
            SuffixOperation,
            PrefixOperation,
            Ternary
        > types_initial;

typedef boost::mpl::push_back<types_initial, New>::type types;
typedef boost::make_variant_over<types>::type Value;

}}

Boost Spirit 无法识别使用 Push_back 添加的最后一个类型 (eddic::ast::New)。当我解析具有此元素的内容时,它会失败并出现以下错误:

eddic: /usr/include/boost/variant/detail/visitation_impl.hpp:264: typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0l>, boost::mpl::v_iter, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, boost::mpl::v_item, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 0>, 21l> >; Visitor = boost::variant, boost::mpl::vector, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Null, eddic::ast::True, eddic::ast::False, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred >, 0> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::assigner; VoidPtrCV = const void*; NoBackupFlag = boost::variant, boost::mpl::vector, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Null, eddic::ast::True, eddic::ast::False, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred, eddic::ast::Deferred >, 0> >, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>::has_fallback_type_; typename Visitor::result_type = void; mpl_::false_ = mpl_::bool_]: Assertion `!"Boost.Variant internal error: 'which' out of range."' failed.

如果我交换两个元素(例如三元和新),新会被正确识别,但三元不会。只有最后一个元素失败了。

我已经尝试使用push_front或vector21,但它没有改变任何东西,它总是最后一个有问题的元素。在我看来,这是因为 Spirit 在将其复制到我的variant_over 类型之前在内部使用了一个变体。

这个问题有解决办法吗?

我可能可以将数量减少到 20 个,但问题是我将来肯定会比这个数量更多。

非常感谢您的任何想法

最佳答案

BOOST_MPL_LIMIT_VECTOR_SIZE 定义为您想要的任何新限制,但达到这么高通常暗示着设计问题,因此可能值得考虑一下。

关于c++ - 20多种变体的Boost Spirit如何使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11630823/

相关文章:

c++ - 获取所有基类 [元编程]

c++ - 读取输入以构造对象

c++ - 这两种在类中动态分配数组的方法有什么区别

c++ - 我如何扩展 boost spirit 语法

c++ - boost::spirit: qi::rule 或包含 qi::rule 作为解析结果的结构

c++ - 如何实例化一个没有默认构造函数的类型的 boost::fusion::vector 成员变量?

c++ - 在 boost MPL 中,如何检查操作是否按预期进行?

c++ - C/C++ : "for" macro to track loops which are running many iterations

c++ - STL 兼容容器

c++ - Boost Spirit 信号成功解析,尽管 token 不完整