提升精神自动规则问题

发布于 2024-09-16 02:25:19 字数 1443 浏览 2 评论 0 原文

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

错误:C:\Program Files (x86)\CodeBlocks\MinGW\boost_1_43_0\boost\variant\variant.hpp|1293|错误:没有调用“boost::detail::variant::make_initializer_node”的匹配函数::apply >、boost::mpl::l_iter、boost::recursive_wrapper、Lang::VarStatement> > >::initializer_node, mpl_::int_<1>; >, boost::mpl::l_iter

谢谢。

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

聚苯硫醚 有些信息我忘了提及。 如果我删除 "else" >> 并更改 > ,它就会起作用。语句>>语句,但是“else”>>语句 应该折叠为仅语句。显式创建“else”作为 qi::lit 没有帮助。

I'm using attribute propagation to construct a syntax tree for a toy language. I've hit a problem at the definition of my if statement, it's hard to tell from the error message but I think the rhs attribute isn't collapsing into the expected attribute. It should collapse to a tuple <double,Statement,optional<Statement>> I think.

The error: 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]

Thanks.

P.S.
I couldn't get the code to display right, there's a plaintext version here: http://freetexthost.com/a3smzx0zk5

P.P.S.
Some information I forogt to mention.
It works if I remove "else" >> and change > statement to >> statement, but "else" >> statement should collapse to just statement. Explicitly creating "else" as a qi::lit doesn't help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

踏雪无痕 2024-09-23 02:25:19

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

因此,表达式暴露的属性

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

是:

tuple <tuple <double, Statement>, optional<Statement> >

它解释了您的编译问题。将表达式重写为:

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

应该可以解决问题(不改变语义)。

The sequence operator>>() and the expectation operator>() do not mix well in terms of attribute handling. If you use both operators in the same expression the overall attribute does not get flattened. That would happen if you were using the one or the other only.

For this reason the attribute exposed by the expression:

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

is:

tuple <tuple <double, Statement>, optional<Statement> >

which explains your compilation problems. Rewriting the epression as:

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

should solve the issue, though (without changing the semantics).

与往事干杯 2024-09-23 02:25:19

呃,好像我无法编辑或评论,所以我必须将此作为答案发布。

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

标识符
%= 词法[(alpha | char_(''))
>>> *(alnum | char
('_'))]
;

表达式
%= 文字
;

文字
%= 真实文字
|字符串文字
;

real_literal
%=双_
;

string_literal
%= 词素['"'
>>> *(char_ - '"')
>>> ''']
;

和以前一样的问题。然而,我第一次并没有很好地调查问题。

在成员函数 '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 < /code>

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>

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

调用上面方法的方法是这样的:

template

variant(const T& operand)
{
    convert_construct(operand, 1L);
}</code>

看起来它试图改为调用这个方法:

template

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>

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

Uh, seems like I can't edit or comment, so I'll have to post this as an answer.

I got around the problem by splitting the rule into an if statement rule and an if-else statement rule. However, the problem is back for my definition of an init declaration.
init_decl
%= identifier
>> -('=' >> expression)
;

identifier
%= lexeme[(alpha | char_(''))
>> *(alnum | char
('_'))]
;

expression
%= literal
;

literal
%= real_literal
| string_literal
;

real_literal
%= double_
;

string_literal
%= lexeme['"'
>> *(char_ - '"')
>> '"']
;

Same problem as before. However, I didn't do a good job of investigation the problem the first time at all.

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

That is this method:

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>

Is this a compiler misunderstanding that is the cause of this error?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文