我正在使用属性传播来构建玩具语言的语法树。我在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]
感谢。
P.S。 我无法让代码显示正确,这里有一个纯文本版本:http://freetexthost.com/a3smzx0zk5
P.P.S。
我要提到的一些信息。
如果我删除"else" >>
并将> statement
更改为>> statement
,则会有效,但"else" >> statement
应该折叠为只是声明。明确地创建“else”作为qi :: lit并没有帮助。
答案 0 :(得分:3)
序列operator>>()
和期望operator>()
在属性处理方面不能很好地融合。如果在同一表达式中使用两个运算符,则整体属性不会变平。如果您只使用这一个,那就会发生。
因此,表达式公开了属性:
if_statement %= "if" > qi::double_ > statement >> -("else" > statement) ;
是:
tuple <tuple <double, Statement>, optional<Statement> >
解释了您的编译问题。将表现重写为:
if_statement %= "if" > qi::double_ > statement > -("else" > statement) ;
应该解决这个问题(不改变语义)。
答案 1 :(得分:0)
我通过将规则拆分为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&, int, mpl_::false_) [with T = const Lang::Elements::Expression, T0_ = double, T1 = std::basic_string, std::allocator >, 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 <typename T>
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>
Remember this error originates from the %= in the init_decl expression. The only variant in this expression is the one contained by the Expression object which is the expression rule's attribute value. The error seems to say that a variant (the type of object Expression contains) is trying to instantiate itself from an Expression, but I can't see this anywhere in the code. Anyway, I added cast operators to the Expression struct that exposes its underlying variant, but still I got the error.
The method that calls the method above is this:
template <typename T>
variant(const T& operand)
{
convert_construct(operand, 1L);
}</code>
It seems like it's trying to call this method instead:
template <typename Variant>
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>
这是编译器误解导致此错误的原因吗?