提升精神自动规则问题

时间:2010-08-21 20:55:55

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

我正在使用属性传播来构建玩具语言的语法树。我在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并没有帮助。

2 个答案:

答案 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>

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