boost::spirit::x3 属性兼容性规则,直觉还是代码?

2021-12-24 00:00:00 c++ boost boost-spirit boost-spirit-x3

是否有文档描述了各种 Spirit::x3 规则定义操作如何影响属性兼容性?

Is there a document somewhere which describes how various spirit::x3 rule definition operations affect attribute compatibility?

我很惊讶:

x3::lexeme[ x3::alpha > *(x3::alnum | x3::char_('_')) ]

无法移动到融合适应的结构中:

could not be moved into a fusion-adapted struct:

struct Name {
    std::string value;
};

暂时去掉了第一个强制字母,但我还是想表达一个规则,定义名称字符串必须以字母开头.这是我需要尝试添加 eps 直到它起作用的那些情况之一,还是有一个明确的原因为什么上述方法不起作用?

For the time being, I got rid of the first mandatory alphabetical character, but I would still like to express a rule which defines that the name string must begin with a letter. Is this one of those situations where I need to try adding eps around until it works, or is there a stated reason why the above couldn't work?

如果这被写在某处,我很抱歉,我找不到它.

I apologize if this has been written down somewhere, I couldn't find it.

推荐答案

如果您不在开发分支上,您就无法修复那个单元素序列自适应错误,所以是的,可能就是这样.

If you're not on the develop branch you don't have the fix for that single-element sequence adaptiation bug, so yeah it's probably that.

>

由于属性转换/传播的通用性,有很多回旋余地,但当然它只是记录在案并最终在代码中.换句话说:没有魔法.

Due to the genericity of attribute transformation/propagation, there's a lot of wiggle room, but of course it's just documented and ultimately in the code. In other words: there's no magic.

在 Qi 时代,我会通过使用 qi::as<>qi::attr_cast<> 拼出所需的转换来修复"这个问题代码>.X3 没有它(还),但你可以使用规则很容易地模仿它:

In the Qi days I'd have "fixed" this by just spelling out the desired transform with qi::as<> or qi::attr_cast<>. X3 doesn't have it (yet), but you can use a rule to mimick it very easily:

生活在 Coliru

#include <iostream>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>

namespace x3 = boost::spirit::x3;

struct Name {
    std::string value;
};

BOOST_FUSION_ADAPT_STRUCT(Name, value)

int main() {

    std::string const input = "Halleo123_1";
    Name out;

    bool ok = x3::parse(input.begin(), input.end(),
            x3::rule<struct _, std::string>{} =
            x3::alpha >> *(x3::alnum | x3::char_('_')),
            out);

    if (ok)
        std::cout << "Parsed: " << out.value << "
";
    else
        std::cout << "Parse failed
";
}

打印:

Parsed: Halleo123_1

自动化

因为 X3 与 c++14 核心语言特性配合得非常好,所以减少输入并不难:

Automate it

Because X3 works so nicely with c++14 core language features, it's not hard to reduce typing:

了解 Boost.Spirit 中的列表运算符 (%)

相关文章