用boolean或enum成员解析为具有提升精神x3

时间:2016-06-10 13:18:41

标签: c++ parsing c++14 boost-spirit boost-spirit-x3

如果我有结构:

struct person{
    bool is_male;
    std::string name;
    std::vector<std::string> friends;
}

enum class gender_t{male, female}
struct person{
        gender_t gender;
        std::string name;
        std::vector<std::string> friends;
}

如何使用boost.spirit X3解析此结构? 一个规则将如何解析像#34; alice male bob&#34;并且解析器返回一个名为alice的对象,该对象是男性并且有一个朋友鲍勃。 如果这个人不是女性,那么如果性别只是明确地说出来会怎么样呢?

2 个答案:

答案 0 :(得分:5)

这正是Spirit的符号表所用的 - 实际上,它是Spirit文档中的主要教程之一(Spirit.X3: Roman Numerals)。

首先,您需要适当调整您的类型:

struct person {
    std::string name;
    gender_t gender;
    std::vector<std::string> friends;
};
BOOST_FUSION_ADAPT_STRUCT(person, name, gender, friends)

N.b。我已经改变了成员的顺序 - 因为我们要解析名称 - &gt;性别 - &gt;朋友们,如果我们以这种方式构建我们的类型,这是最简单的。现在,解析:

person parse_person(std::string const& str) {
    namespace x3 = boost::spirit::x3;

    struct gender_table : x3::symbols<gender_t> {
        gender_table() {
            add ("male"   , gender_t::male)
                ("female" , gender_t::female)
            ;
        }
    } const gender;
    auto const word = x3::lexeme[+~x3::space];
    auto const parser
      =    word                                  // name
        >> (gender | x3::attr(gender_t::female)) // gender
        >> +word                                 // friends
      ;

    person ret{};
    x3::phrase_parse(str.cbegin(), str.cend(), parser, x3::space, ret);
    return ret;
}

Online Demo

(如果您无法更改数据成员的顺序以便于解析,那么here是一种使所有这些非侵入性的方法。)

答案 1 :(得分:0)

  

要将boost spirit x3用作解析器,请访问此link

     

The documentation of boost::Spirit

问题:

  

如果这个人不是女性,那么性别是否只是明确表示会如何呢?

我认为使用enum class Gender : uint8_t更灵活,因为您可以添加未指定的性别。