1

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

谢谢。

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

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

4

2 回答 2

3

在属性处理方面,序列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) ;

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

于 2010-08-23T12:14:43.003 回答
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(
      Variant& operand
    , long
    , mpl::true_// is_foreign_variant
    )
{
    convert_copy_into visitor(storage_.address());
    indicate_which(
          operand.internal_apply_visitor(visitor)
        );
}</code>

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

于 2010-08-27T18:22:46.233 回答