4

文法を表現しようとしたとき (Lua の小さなサブセット、 mini_c とほぼ同じ; somplexない)、問題に直面しました。 8GB RAM を搭載したシステム)。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 --> statement_level --> function_list_level のようなクラスのチェーンがある場合、それらは (それぞれ) それぞれに配置する必要がありますか、代わりにチェーンの最後のクラスに配置する必要がありますか? )?

このような問題の主なポイントは、文法の表現手段を単純化することによって、コンパイルの複雑さ (および、コンパイル時間) を削減することです。

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 に答える