将包含字符串成员的类调整为合成属性

Kon*_*lph 7 c++ boost-spirit boost-fusion

我正在尝试将字符串解析为symbol包含std::string成员的自定义类型的属性.我以为我可以BOOST_FUSION_ADAPT_STRUCT在这里使用,但这不起作用.

如果我宣布规则是rule<It, std::string(), space_type>有效的.如果我将其定义为rule<It, symbol(), space_type>失败,并显示错误"no type name value_typein symbol".我认为Spirit正在尝试将值字符附加到属性中,该属性会按预期失败.但是,如果没有添加额外的中间规则来捕获std::string属性,是不是有办法使这项工作成功?

这是完整的MWE:

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>

struct symbol 
{ 
    std::string repr; 
};

BOOST_FUSION_ADAPT_STRUCT(symbol, (std::string, repr))

namespace qi = boost::spirit::qi;

template <typename Iterator>
struct test_grammar : qi::grammar<Iterator, symbol(), qi::ascii::space_type> {
    test_grammar() : test_grammar::base_type{start} {
        start = qi::lexeme[+qi::char_("a-z")];
    }

    qi::rule<Iterator, symbol(), qi::ascii::space_type> start;
};

#include <iostream>

auto main() -> int {
    test_grammar<std::string::iterator> grammar{};
    auto input = std::string{"test"};
    auto output = symbol{};
    auto e = end(input);
    if (qi::phrase_parse(begin(input), e, grammar, qi::ascii::space, output))
        std::cout << output.repr;
}
Run Code Online (Sandbox Code Playgroud)

seh*_*ehe 2

正如您从链接的欺骗中看到的那样,您可以通过放置适当的qi::eps.

    start = qi::eps >> qi::lexeme[+qi::char_("a-z")];
Run Code Online (Sandbox Code Playgroud)

观看Coliru 现场直播

但是,也有qi::eps不保存的情况。(稍后将尝试查找链接)。因此,我开始倾向于使用“老式方法”来实现属性兼容性:

#include <boost/spirit/include/qi.hpp>

struct symbol 
{ 
    std::string repr; 

    symbol(std::string repr = std::string()) : repr(std::move(repr)) {}
};

namespace qi = boost::spirit::qi;

template <typename Iterator>
struct test_grammar : qi::grammar<Iterator, symbol(), qi::ascii::space_type> {
    test_grammar() : test_grammar::base_type(start) {
        using namespace qi;

        start = as_string[ lexeme[ +char_("a-z") ] ];
    }

    qi::rule<Iterator, symbol(), qi::ascii::space_type> start;
};

#include <iostream>

auto main() -> int {
    test_grammar<std::string::iterator> grammar{};
    auto input = std::string{"test"};
    auto output = symbol{};
    auto e = end(input);
    if (qi::phrase_parse(begin(input), e, grammar, qi::ascii::space, output))
        std::cout << output.repr;
}
Run Code Online (Sandbox Code Playgroud)

这对编译器来说也可能更轻一些。也可以在 Coliru 上观看直播。

如果所有其他方法都失败了,您可以鱼与熊掌兼得,因为属性转换/分配是库中的自定义点。