Boost-Spirit自动规则问题
我正在使用属性传播为玩具语言构建语法树。我在if语句的定义上遇到了一个问题,很难从错误消息中分辨出来,但我认为rhs属性没有塌陷到预期的属性中。我认为它应该折叠成一个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>语句时没有匹配的
元组
错误: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>