用精神解析成类?
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);
}
}
struct
和 class
¹ 没有区别。
除此之外,人们通常的意思是 "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"
的历史
下面是来自 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);
}
}
struct
和 class
¹ 没有区别。
除此之外,人们通常的意思是 "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"
的历史