2016-06-10 82 views
1

布尔或枚举成员结构如果我有一个结构:解析成与提升精神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这个结构? 规则如何看起来像解析一个字符串,如“爱丽丝男性鲍勃”和解析器返回一个名称爱丽丝,这是男性和一个朋友鲍勃的对象。 如果性别只是明确表示,如果该人不是女性,它会是什么样子?

+3

我没有得到问题...你试图解决这个问题的代码是什么?它只是分割一个空格分隔的字符串。 –

+0

你有什么尝试?我认为你不太可能找到愿意为你编写代码的人,但是如果你向我们展示你迄今为止所尝试的内容,那么当时有人可能愿意帮助你。 – SirGuy

+0

解析为结构是不是问题,但我不知道如何解析到一个枚举的结构,这就是我甚至没有想法的问题 – Exagon

回答

3

这正是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) 

注:我改变了成员的顺序 - 因为我们想解析名字 - >性别 - >朋友,如果我们以这种方式构造我们的类型,这也是最简单的。现在,解析:

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是一种方法,使这一切是非的侵入性)

+3

我认为'parser = word >>(性别| x3 :: attr(gender_t :: female))>> + word'也可以。 – llonesmiz

+0

@jv_:是的,很大的改进,谢谢!我的解决方案并没有让我满意,但我想不出另一种不涉及'x3 :: rule'的非正式手段。它现在是如此明显...; - ] – ildjarn

+0

哇与x3 :: attr()这个答案是完美的,正是我一直在寻找。谢谢 – Exagon

0

对于使用boost spirit x3作为解析器,请访问此link

The documentation of boost::Spirit

对于这样的问题:

会如何看待一样,如果性别是唯一明确表示,如果人是不是女的?

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

+2

我真的很感兴趣的解析与提升精神x3直接进入结构与枚举或bool成员,我的例子只是一个MCVE – Exagon