2017-06-16 60 views
2

以下是boost spirit文档中的employee.cpp源文件。它是'结构员工',后面是一个宏,它告诉'结构员工'的聚合,其次是员工解析器。使用精神解析类?

我想适应这个为我的目的,而不是使用'结构员工',我有一些我想用来代替'结构员工'的类。

我正在试图替换类结构员工',但我没有看到宏融合做到这一点?而我不想把它放在结构体中的原因是因为我不得不将它从struct复制到我的类中,而这看起来没有必要,更不用说性能问题了。

经过多思考之后,我可能不会理解Fusion和元组的用途,因此,也许我必须这样使用它,然后将数据移动到我自己的类结构中。

任何指导?

namespace client { namespace ast 
{ 
    /////////////////////////////////////////////////////////////////////////// 
    // Our employee struct 
    /////////////////////////////////////////////////////////////////////////// 
    struct employee 
    { 
     int age; 
     std::string surname; 
     std::string forename; 
     double salary; 
    }; 

    using boost::fusion::operator<<; 
}} 

// We need to tell fusion about our employee struct 
// to make it a first-class fusion citizen. This has to 
// be in global scope. 

BOOST_FUSION_ADAPT_STRUCT(
    client::ast::employee, 
    (int, age) 
    (std::string, surname) 
    (std::string, forename) 
    (double, salary) 
) 

namespace client 
{ 
    /////////////////////////////////////////////////////////////////////////////// 
    // Our employee parser 
    /////////////////////////////////////////////////////////////////////////////// 
    namespace parser 
    { 
     namespace x3 = boost::spirit::x3; 
     namespace ascii = boost::spirit::x3::ascii; 

     using x3::int_; 
     using x3::lit; 
     using x3::double_; 
     using x3::lexeme; 
     using ascii::char_; 

     x3::rule<class employee, ast::employee> const employee = "employee"; 

     auto const quoted_string = lexeme['"' >> +(char_ - '"') >> '"']; 

     auto const employee_def = 
      lit("employee") 
      >> '{' 
      >> int_ >> ',' 
      >> quoted_string >> ',' 
      >> quoted_string >> ',' 
      >> double_ 
      >> '}' 
      ; 

     BOOST_SPIRIT_DEFINE(employee); 
    } 
} 

回答

3

structclass¹之间没有什么区别。

这样一来,人们通常所说的“我希望没有直接数据成员(”字段“)访问的类”。

现在我可以直接点你BOOST_FUSION_ADAPT_ADT。这就是你正在寻找的。

但是

这意味着您已经为所有数据成员公开了setter。这是一个巨大的反模式2,因为它只是导致准类3。

考虑使用工厂函数(使用凤凰从语义动作调用适应他们//但看到Boost Spirit: "Semantic actions are evil"?),或者确实有一个干净的AST表示您然后用于构建从域对象图。

如果你不能这样做(因为副本),你不能真正负担Spirit V2 IMO。 Spirit致力于(改变)语法的快速开发/原型,同时不会产生残酷的代码。但是,如果您不能负担拷贝它的时间以手工卷解析器(或移动到精神X3)


¹字面上唯一的区别是struct使所有成员的公共默认,但你仍然可以使用private:protected:

²可能起源于Java的POJO或 “豆” 的历史

³"Pseudo-Classes and Quasi-Classes Confuse Object-Oriented Programming"