使用精神解析成课程?

时间:2017-06-16 04:59:43

标签: c++ boost-spirit boost-fusion

以下是boost spirit文档中的employee.cpp源文件。它是'struct employee'后跟一个宏,它告诉我们关于'struct employee'的融合,然后是员工解析器。

我正在尝试根据我的目的调整这个,但是我没有使用'struct employee',而是使用了许多类来代替'struct employee'。

我正在尝试为类替换'struct employee',但我没有看到宏在融合中做到这一点?我不想把它放在结构中的原因是因为我必须将它从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);
    }
} 

1 个答案:

答案 0 :(得分:3)

structclass¹之间没有区别。

除此之外,人们通常所说的是“我希望没有直接数据成员(”字段“)访问的课程。”

现在我可以直截了当地指出BOOST_FUSION_ADAPT_ADT。这就是你要找的东西。

<强> 然而

这意味着您已经为所有数据成员公开了setter。这是一个巨大的反模式²,因为它只会导致Quasi-Classes³。

考虑使用工厂函数(使用Phoenix调整它们来调用语义操作//但请参阅Boost Spirit: "Semantic actions are evil"?),或者确实有一个干净的AST表示,然后然后用于构建域对象图来自。

如果你负担不起(因为副本),你真的买不起Spirit V2 IMO。 Spirit旨在快速开发/改变(改变)语法,同时不会产生恶劣的代码。但是,如果你买不起副本,那么就可以手动翻译你的解析器(或转移到Spirit X3)

¹字面上唯一的区别是struct默认情况下会公开所有成员,但您仍然可以使用private:protected:

²可能源于Java的PoJo或“Bean”的历史

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