用精神解析成类?

Using spirit to parse into classes?

下面是来自 boost spirit 文档的 employee.cpp 源文件。它是 'struct employee' 后跟一个告诉融合有关 'struct employee' 的宏,然后是员工解析器。

我正在尝试根据我的目的对此进行调整,但我没有使用 'struct employee',而是想使用一些 class 来代替 'struct employee'.

我正在尝试用 class 替换 'struct employee',但我没有看到在融合中执行此操作的宏?我不想把它放在结构中的原因是我必须将它从结构复制到我的 class,这似乎是不必要的,更不用说性能影响了。

仔细考虑之后,我可能不理解 Fusion 和元组的用途,因此,也许我必须那样使用它,然后将数据移动到我自己的 class 结构中。

有指导吗?

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);
    }
} 

structclass¹ 没有区别。

除此之外,人们通常的意思是 "I want classes without direct data member ("字段") 访问"。

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

不过.

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

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

如果您负担不起(因为副本),那么您就真的买不起 Spirit V2 IMO。 Spirit 适合快速 development/prototyping 的(更改)语法,同时不会生成糟糕的代码。但是如果你买不起副本,是时候手动滚动你的解析器了(或者移动到 Spirit X3)


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

² 可能起源于 Java 的 PoJo 或 "Bean"

的历史

³ "伪类与准类 混淆面向对象编程