当我试图表达语法(Lua的小子集,几乎与 mini_c 相同;不那么复杂)时,我遇到了问题: g ++ 驱动程序提供一段时间后, gas 和 gas 会崩溃(当系统内部消耗大约500MB时,内存消耗为8GB)。我查看Compiler Tutorial并发现,我们应该将复杂的语法分解为较小的语法。
问题是它是强制性的,我们应该让类(由规则集组成)自己的语法(即使它们继承自boost::spirit::qi::grammar
)? IOW,我们可以将规则划分为子集并将它们分布在简单类声明之间,作为字段,有意定义(例如,在单独的标头中)并明确地将每个类(在实践中,类模板)实例化为单独的翻译单位,以避免上述崩溃?如果答案是肯定的,那么如何使用宏BOOST_SPIRIT_DEBUG_NODES
和结构的位置,如:
using namespace boost::spirit;
qi::on_error< qi::fail >(function_definition_,
error_handler_function(_error_handler)(
"Error! Expecting ", qi::_4, qi::_3));
和
using namespace boost::spirit;
qi::on_success(function_name_,
annotation_function(_error_handler.iters_)(qi::_val, qi::_1));
应该放置它们的位置(例如,如果我们有类似的链,例如:expression_level - &gt; statement_level - &gt; function_list_level, - 那么它们必须放在每个(分别)中,或者放在最后链中的类?)?
这个问题的要点是通过简化语法的表达方式来降低编译的复杂性(以及编译时间)。
答案 0 :(得分:3)
请记住:它只是C ++类。
所以,
是的,您可以让类充当规则的“哑”容器。实际上,如果您的迭代器/跳过器没有变化,您可以只使用命名空间:
//header
namespace G1 { extern const qi::rule<It, attr()> R1; }
//cpp
namespace G1 { const qi::rule<It, attr()> R1 = qi::eps /* ... */; }
我认为这种方法主要采用Spirit X3 (?)
支持组合优于继承(为您的编译器提供更多自由)
-g0
)-Os
或无优化(-O0
)禁用代价高昂的功能:
BOOST_SPIRIT_DEBUG
BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
此外,如果您希望隐藏公共界面中的所有精神,则会出现pimpl / file-static匿名命名空间。