简单的动作会破坏Spirit X3的结果 [英] Simple sematic action destroys the result in Spirit X3

查看:80
本文介绍了简单的动作会破坏Spirit X3的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个Spirit X3解析器

I have this Spirit X3 parser

    auto xyz_def = 
        x3::omit[x3::int_] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)
    ;

毫无疑问地解析这样的东西

Which parses, with no problem something like this

2
Comment
H 1.2 3.2 4.5
C 1.1 9.1 8.5

现在,我想使用(而不是完全忽略)第一个整数作为提示来帮助构建矢量(来自Kleen *). 为此,我做了:

Now I want to use (instead of completely ignoring) the first integer as a hint to help build the vector (from the Kleen*). To do that I do:

    auto xyz_def = 
        x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)]) >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)
    ;

但是,当我这样做时,尽管解析函数成功了,但结果却是空的.这尤其神秘,因为原则上,语义动作没有明显的副作用.

However, when I do this, although the parsing function succeed, I have an empty result. This is particularly mysterious because the sematic action, in principle, has no salient side effect.

我发现了这种解决方法,该方法是明确引入所有语义动作.

I found this workaround, which was to introduce all the sematic actions explicitly.

    auto xyz_def = 
        x3::omit[x3::int_[([](auto& ctx){x3::_val(ctx).reserve(x3::_attr(ctx));})]] >> x3::eol >> 
        (x3::lexeme[+(x3::char_ - x3::eol)])[([](auto& ctx){x3::_val(ctx).comment = x3::_attr(ctx);})] >> x3::eol >>
        (*(chemical::parser::atom >> x3::eol)[([](auto& ctx){x3::_val(ctx).atoms.insert(end(x3::_val(ctx).atoms), x3::_attr(ctx));})])
    ;

这显然是一个过大的杀伤力. 为什么当我在第一个元素中仅添加一个语义动作时,我必须为所有人添加语义动作?

This is obviously an overkill. Why is it that when I add just one semantic actions in the first element, I have to add sematic actions for all?

我最近问了一个类似的问题,但是我使用了错误版本的Spirit(Qi),并且现在我还使用属性而不是捕获lambda,因此我可以定义独立的规则.

I recently asked a similar question, but I was using the wrong version of Spirit (Qi) and I am also using attributes now instead of capturing lambdas, so that I can define self-contained rules.

完整代码为此处,可以粘贴到

The full code is here, can be pasted in https://wandbox.org/

推荐答案

偶然地,在阅读rule /usr/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp的代码时,我注意到它具有第三个模板参数,称为力属性".

By accident, while reading the code of rule /usr/include/boost/spirit/home/x3/nonterminal/detail/rule.hpp I noticed that it has a third template parameter called "force attributes".

    template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
    struct rule;

好吧,事实证明,放下true可使预期结果奏效.

Well, it turns out that putting true made the expected result to work.

    x3::rule<class xyz_, chemical::xyz, true> const xyz = "xyz";

(之前是x3::rule<class xyz_, chemical::xyz> const xyz = "xyz";)

这篇关于简单的动作会破坏Spirit X3的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆