2017-06-16 63 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"