【问题标题】:Using spirit to parse into classes?使用精神解析成类?
【发布时间】:2017-06-16 04:59:43
【问题描述】:

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

我正在尝试根据我的目的对其进行调整,但我没有使用“struct employee”,而是想使用一些类来代替“struct employee”。

我正在考虑尝试为类替换“struct employee”,但我没有看到宏在融合中可以做到这一点?我不想把它放在结构中的原因是因为我必须将它从结构复制到我的类,这似乎没有必要,更不用说性能损失了。

再想一想,我可能不明白 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);
    }
} 

【问题讨论】:

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


    【解决方案1】:

    structclass¹ 没有区别。

    除此之外,人们通常的意思是“我想要没有直接数据成员(“字段”)访问的类”。

    现在我可以直接指向BOOST_FUSION_ADAPT_ADT。这就是你要找的东西。

    但是

    这意味着无论如何您已经为所有数据成员公开了设置器。这是一个巨大的反模式²,因为它只会导致准类³。

    考虑使用工厂函数(使用 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"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-04
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多