Boost-Spirit自动规则问题

Boost-Spirit自动规则问题,boost,attributes,boost-spirit,boost-spirit-qi,propagation,Boost,Attributes,Boost Spirit,Boost Spirit Qi,Propagation,我正在使用属性传播为玩具语言构建语法树。我在if语句的定义上遇到了一个问题,很难从错误消息中分辨出来,但我认为rhs属性没有塌陷到预期的属性中。我认为它应该折叠成一个元组 错误:C:\Program Files(x86)\CodeBlocks\MinGW\boost\u 1\u 43\u 0\boost\variant\variant.hpp | 1293 |错误:调用'boost::detail::variant::make_initializer\u node::apply>语句时没有匹配的

我正在使用属性传播为玩具语言构建语法树。我在if语句的定义上遇到了一个问题,很难从错误消息中分辨出来,但我认为rhs属性没有塌陷到预期的属性中。我认为它应该折叠成一个
元组


错误:
C:\Program Files(x86)\CodeBlocks\MinGW\boost\u 1\u 43\u 0\boost\variant\variant.hpp | 1293 |错误:调用'boost::detail::variant::make_initializer\u node::apply>语句时没有匹配的函数
,但是
“else”>>语句
应该折叠为just语句。将“else”显式创建为qi::lit没有帮助。

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

因此,表达式公开的属性为:

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


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

嗯,似乎我无法编辑或评论,所以我必须将此作为答案发布

我通过将规则拆分为if语句规则和if-else语句规则来解决这个问题。然而,问题又回到了我对init声明的定义上。
init_decl
%=标识符
>>-('='>>表达式)
;

标识符
%=词素[(α|字符(“”))
>>*(alnum|char(“|”)]
;

表达式
%=文字
;

literal
%=实数
|字符串文字
;

real\u literal
%=双倍_
;

string\u literal
%=词素['“'
>>*(字符-“”)
>> '"']
;

和以前一样的问题。但是,我第一次没有很好地调查这个问题

在成员函数“void boost::variant::convert_构造(T&,int,mpl_::false_)”中[with T=const Lang::Elements::Expression,T0=double,T1=std::basic\u string,std::allocator>,T2=boost::detail::variant::void\uu,T3=boost::detail::variant::void\uu,T4=boost::detail::variant::void\uu,T5=boost::detail::variant::variant::void,T7=boost::detail::vari

这就是这个方法:

模板

请记住,此错误源于init_decl表达式中的%=。此表达式中唯一的变量是表达式对象包含的变量,它是表达式规则的属性值。此错误似乎表示变量(对象表达式的类型包含)正在尝试从表达式实例化自身,但我在代码中的任何地方都看不到这一点。无论如何,我在表达式结构中添加了强制转换运算符,以公开其基础变量,但仍然出现了错误

调用上述方法的方法如下:

模板

变量(常量T和操作数) { 转换构造(操作数,1L); }
它似乎正在尝试调用此方法:

模板

void-convert\u构造( 变量和操作数 长的 ,mpl::true//是外部变量 ) { 将_copy_转换为访问者(存储地址()); 指明哪一个( 操作数.内部应用访问者(访问者) ); }

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

好主意,但它仍然不起作用。如果我删除了else,它就会起作用,这是我唯一的线索。好的,那么我希望看到一个可以编译的小型自包含测试。否则,几乎不可能判断出问题所在。
tuple <tuple <double, Statement>, optional<Statement> >
if_statement %= "if" > qi::double_ > statement > -("else" > statement) ;
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>
variant(const T& operand) { convert_construct(operand, 1L); }</code>
void convert_construct( Variant& operand , long , mpl::true_// is_foreign_variant ) { convert_copy_into visitor(storage_.address()); indicate_which( operand.internal_apply_visitor(visitor) ); }</code>