4

当我试图表达语法时(Lua 的小子集,几乎与mini_c相同;不是那么复杂),然后我遇到了问题:g++驱动程序提供了一段时间后粉碎的气体气体(当达到大约 500MB 的总内存消耗时具有 8GB RAM 的系统)。我查看了编译器教程,发现我们应该将复杂的语法分解成更小的语法。

问题是我们应该使类(由规则集组成)本身是语法(即让它们继承自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));

?

它们应该放在哪里(例如,如果我们有类链,例如:表达式级别 --> 语句级别 --> 函数列表级别,那么它们必须放置在每个(分别)中,或者相反,放在链中的最后一个类中? )?

此类问题的主要目的是通过简化语法表达方式来降低编译复杂度(以及编译时间)。

4

1 回答 1

3

请记住:这只是 C++ 类。

所以,

  1. 您可以按照自己喜欢的方式将资产拆分为 TU。
  2. AFAICT on_error 和 debug 通过引用附加到它们的主题规则,因此您可以将它们放在任何地方
  3. 是的,你可以让类充当规则的“愚蠢”容器。事实上,如果你的迭代器/船长没有变化,你可以只使用命名空间:

    //header
    namespace G1 { extern const qi::rule<It, attr()> R1; }
    
    //cpp
    namespace G1 { const qi::rule<It, attr()> R1 = qi::eps /* ... */; }
    

    我认为这种方法主要用于 Spirit X3 (?)

  4. 喜欢组合而不是继承(给你的编译器更多的自由)

  5. 禁用调试信息 ( -g0)
  6. 尝试优化大小-Os或不优化 ( -O0)
  7. 禁用昂贵的功能:

    • BOOST_SPIRIT_DEBUG
    • 利用BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
    • 避免语义动作

此外,如果您希望从公共界面中隐藏所有精神,则可以使用 pimpl/file-static 匿名命名空间。

于 2013-11-13T01:17:05.900 回答