【问题标题】:Boost Spirit auto-rule problemBoost Spirit自动规则问题
【发布时间】:2010-08-21 20:55:55
【问题描述】:

我正在使用属性传播来构建玩具语言的语法树。我在 if 语句的定义中遇到了问题,很难从错误消息中分辨出来,但我认为 rhs 属性没有折叠到预期的属性中。我认为它应该折叠为tuple <double,Statement,optional<Statement>>

错误:C:\Program Files (x86)\CodeBlocks\MinGW\boost_1_43_0\boost\variant\variant.hpp|1293|error: no matching function for call to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list3<boost::recursive_wrapper<Lang::CompoundStatement>, boost::recursive_wrapper<Lang::IfStatement>, Lang::VarStatement> > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::list2<boost::recursive_wrapper<Lang::IfStatemen [error cuts out here]

谢谢。

附: 我无法正确显示代码,这里有一个纯文本版本:http://freetexthost.com/a3smzx0zk5

附言 一些我忘记提及的信息。 如果我删除"else" >> 并将> statement 更改为>> statement,它会起作用,但"else" >> statement 应该折叠为仅声明。将“else”显式创建为 qi::lit 没有帮助。

【问题讨论】:

    标签: boost attributes boost-spirit boost-spirit-qi propagation


    【解决方案1】:

    序列operator>>() 和期望operator>() 在属性处理方面不能很好地混合。如果在同一个表达式中使用这两个运算符,则整体属性不会变平。如果您只使用其中一种,就会发生这种情况。

    因此表达式暴露的属性:

    if_statement %= "if" > qi::double_ > statement >> -("else" > statement) ;
    

    是:

    tuple <tuple <double, Statement>, optional<Statement> >
    

    这解释了您的编译问题。将 epression 重写为:

    if_statement %= "if" > qi::double_ > statement > -("else" > statement) ;
    

    应该可以解决这个问题(不改变语义)。

    【讨论】:

    • 好主意,但仍然无法正常工作。如果我删除 else 就可以工作,这是我唯一的线索。
    • 好的,那我想看看一个我可以编译的小型独立测试。否则几乎不可能分辨出哪里出了问题。
    【解决方案2】:

    呃,我好像无法编辑或评论,所以我必须发布这个作为答案。

    我通过将规则拆分为 if 语句规则和 if-else 语句规则来解决这个问题。但是,问题又出现在我对 init 声明的定义中。
    init_decl %= identifier >> -('=' >> expression) ;

    identifier %= lexeme[(alpha | char_('')) >> *(alnum | char('_'))] ;

    expression %= literal ;

    literal %= real_literal | string_literal ;

    real_literal %= double_ ;

    string_literal %= lexeme['"' >> *(char_ - '"') >> '"'] ;

    和以前一样的问题。但是,我在第一次的时候并没有很好地调查问题。

    In member function 'void boost::variant::convert_construct(T&amp;, int, mpl_::false_) [with T = const Lang::Elements::Expression, T0_ = double, T1 = std::basic_string, std::allocator &gt;, T2 = boost::detail::variant::void_, T3 = boost::detail::variant::void_, T4 = boost::detail::variant::void_, T5 = boost::detail::variant::void_, T6 = boost::detail::variant::void_, T7 = boost::detail::vari

    就是这个方法:

    template &lt;typename T&gt;

    void convert_construct(
          T& operand
        , int
        , mpl::false_ = mpl::false_() // is_foreign_variant
        )
    {
        // NOTE TO USER :
        // Compile error here indicates that the given type is not 
        // unambiguously convertible to one of the variant's types
        // (or that no conversion exists).
        //
        indicate_which(
              initializer::initialize(
                  storage_.address()
                , operand
                )
            );
    }</code>
    

    请记住,此错误源自 init_decl 表达式中的 %=。此表达式中唯一的变体是 Expression 对象包含的变体,它是表达式规则的属性值。该错误似乎表明一个变体(表达式包含的对象类型)正在尝试从一个表达式实例化自己,但我在代码中的任何地方都看不到这一点。无论如何,我将强制转换运算符添加到暴露其底层变体的 Expression 结构中,但仍然出现错误。

    调用上面方法的方法是这样的:

    template &lt;typename T&gt;

    variant(const T& 操作数)
    {
        转换构造(操作数,1L);
    }
    

    它似乎正在尝试调用此方法:

    模板

    void convert_construct(
          变体&操作数
        , 长
        , mpl::true_// is_foreign_variant
        )
    {
        convert_copy_into 访问者(storage_.address());
        指示_哪个(
              操作数.internal_apply_visitor(访问者)
            );
    }
    

    这是导致此错误的编译器误解吗?

    【讨论】:

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