0

Linux プラットフォームで C++ を使用するメタ プログラミング言語のパーサーに取り組んでいます。現在、パーサーがいくつかの追加機能を提供するために、オプション/ロング オプションを実装する必要があります。基本的に、ユーザーが追加のオプションを渡す場合、パーサーはテキスト ファイルの解析中に統計を保存する必要があります。

それを実装するには2つの方法が考えられます。1 つの方法は、ユーザーによって入力されたオプションを格納するためにユーザー グローバルを使用することです。もう 1 つの方法は、オプションを格納するシングルトン クラスを作成することです。そのため、他に実装する方法があれば教えていただきたいです。それを実装するための最良/最も推奨される方法は何ですか? 前もって感謝します。

よろしく、

K.ハイン

4

2 に答える 2

2

グローバルとシングルトンの両方が、パーサーの単体テストを苦痛にします。パーサーがさまざまなオプションでどのように動作するかを単体テストするには、テストでグローバルを変更する必要があります。このようなアプローチには、少なくとも 2 つの問題があります。グローバルとクラスの間に明確な関連性がありません。実装を調べる以外に、リーダーは、クラス内でどのグローバルが使用されているか、およびそれらが動作にどのように影響するかを知ることができません。そのようなグローバルは const にできません (メインで設定されているため)。そのため、パーサーが作成されると、オプションの値を変更できないという通信と強制の機能が失われます。

従来のシングルトンは、実装を置き換える方法がなく、通常はテストを完全に妨げるため、グローバルよりもさらに悪いです。

適切なアプローチは、オプションを格納する const オブジェクトをパーサー コンストラクターに挿入することです。ただし、このオブジェクトにコマンド ライン解析ロジックを配置しないでください。そうしないと、テストでオブジェクトを便利に使用できなくなります。

于 2012-09-30T07:29:47.057 に答える
1

ヤンの答えを拡張するには、次のような関数があります。

bool my_parser(const parser_options &options);

parser_options型は単純な構造にすることができます。たとえば、次のようになります。

struct parser_options
{
    FILE *source_file;
    bool warnings_as_errors;
    std::shared_ptr<error_handler> eh;
    ...
};

は次のerror_handlerように定義できます。

struct error_handler
{
    virtual void error(int code, const char *message) = 0;
    virtual void warning(int code, const char *message) = 0;
    virtual ~error_handler() {}
};

次に、プログラムは次のようなことを行います。

int main(int argc, const char *argv)
{
    parser_options options;
    // process argc/argv options here, adding them to options, e.g.:
    //     case WARN_AS_ERROR: options.warnings_as_errors = true; break;
    return my_parser(options, &error) ? ERROR_SUCCESS : ERROR_FAILURE;
}

これにより、直接呼び出すテストを記述し、コマンド ライン処理とは独立してmy_parser設定し、別のものを指定することができます (たとえば、情報を機械可読形式にフォーマットするもの)。parser_optionserror_handler

注: これは、パーサーの完全な設計を意図したものではありません。これは、このようなものを設計する方法の単なる例です。

注: この設計は、パイプラインを制御するようにアプリケーションを構成できる場合 (最適化なし、内部 AST の出力、内部表現、アセンブリ コード、プリプロセッサ出力など) をテストするために厳密に必要というわけではありません。ただし、コマンド ライン プログラム (GUI アプリケーション/IDE、静的解析ツールなど) を直接呼び出すことなく、さまざまなプログラムで使用できるため、設計はより柔軟です。

于 2012-09-30T10:23:25.573 に答える