ヤンの答えを拡張するには、次のような関数があります。
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_options
error_handler
注: これは、パーサーの完全な設計を意図したものではありません。これは、このようなものを設計する方法の単なる例です。
注: この設計は、パイプラインを制御するようにアプリケーションを構成できる場合 (最適化なし、内部 AST の出力、内部表現、アセンブリ コード、プリプロセッサ出力など) をテストするために厳密に必要というわけではありません。ただし、コマンド ライン プログラム (GUI アプリケーション/IDE、静的解析ツールなど) を直接呼び出すことなく、さまざまなプログラムで使用できるため、設計はより柔軟です。