「スタイルチェッカー」の主な問題は、スタイルがアートのようなものであるということです。良いスタイルとそうでないものについては、誰もが異なる意見を持っています。その意味するところは、スタイルチェッカーは常に地元のアートの好みに合わせてカスタマイズする必要があるということです。
これを正しく行うには、シンボル定義、スコープルール、理想的にはさまざまな種類のフロー分析にアクセスできる完全なC++パーサーが必要です。AFAIK、CppCheckは正確な解析またはシンボルテーブル定義を提供しないため、エラーチェックを詳細かつ正確にすることはできません。CoverityとFortifyは、EDGフロントエンドを使用してこれらの方針に沿って何かを提供していると思います。彼らのツールがシンボルテーブルまたはデータフロー分析へのアクセスを提供するかどうかはわかりません。Clangがやってくる。
また、スタイルチェックを作成する方法も必要です。すべてのツールがASTとおそらくシンボルテーブルへのアクセスを提供していると思います。また、C ++のような大きな言語では難しい、ASTを詳しく知ることを犠牲にして、独自のチェックを手動でコーディングできます。CoverityとFortifyには、いくつかのチェックを指定するためのDSLのようなスキームがあると思います。
スタイルが正しくないコードを修正する場合は、コード表現を変更できるものが必要です。CoverityとFortifyはこのAFAIKを提供していません。Clangには、ASTを変更してコードを再生成する機能があると思います。ツリーハッキングロジックをコーディングして正しく実行するには、AST構造についてかなり深い知識が必要です。
DMS Software ReengineeringToolkitとそのC++フロントエンドは、これらの機能のほとんどを提供します。DMSは、C ++フロントエンドを使用して、ANSI C ++ 11、GCC4(C ++ 11拡張機能付き)およびMSVS 2010(C ++ 11拡張機能付き)を解析できます[2021年5月更新:完全なC++17およびほとんどのC++20]完全な型情報を使用してASTとシンボルテーブルを構築します。任意の式のASTノードのタイプを要求することもできます。現在、DMSは制御フローを計算しますが、C++のデータフローは計算しません。
AST APIを使用すると、任意のチェックを手続き的にコーディングできます。または、ASTに変更を加えて問題を修正すると、DMSのprettyprinterは、コメントと保存されたリテラル形式情報(基数など)を含む完全でコンパイル可能なソーステキストを再生成できます。これを行うには、他のツールと同じようにAST構造を知っている必要がありますが、DMS C ++文法規則と同型であるため、はるかに簡単に知ることができます。C ++フロントエンドには、C++文法が付属しています。[DMSはこれを可能にするためにGLRパーサーを使用します]。
さらに、C ++自体の表面構文を使用して、DMSのルール仕様言語を使用してパターンと変換を記述できます。OPを「非STL例外をスローしない」とコーディングする場合があります。
pattern nonSTLexception(i: IDENTIFIER):statement
= " throw \i; " if ~derived_from_STD_exception(i);
(メタ)引用符内のものは、パターンマッチングエスケープを含むC ++ソースコードです。たとえば、「\ i」は、ルールに従ってC++IDである必要があるプレースホルダー変数「i」を指します。「投げる\i;」全体 句はC++の「ステートメント」(C ++文法の非終端記号)である必要があります。ルール自体は主に一致する構文を表現しますが、一致するサブツリー(この場合は「\ i」が一致するもの)に適用されるセマンティックチェック(「〜is_valent_from_STD_exception」など)を呼び出すことができます。
このようなパターンを書く際に、ASTの形を知る必要はありません。パターンはそれを認識しており、自動的に照合されます。ASTウォーカーをコーディングしたことがある場合は、これがいかに便利であるかを理解できます。
一致はASTノードを認識しているため、正確な位置(ファイル/行/列)を認識しているため、正確な位置情報を含むレポートを簡単に生成できます。
カスタムルーチン"inherits_from_STD_exception"を追加して、そのルーチンに渡される識別子ツリーノードが(OPの必要に応じて)std::exceptionから派生したクラスであることを確認する必要があります。これには、シンボルテーブルで「std :: exception」を見つけ、識別子ツリーノードのシンボルテーブルエントリがクラス宣言であり、std :: exceptionまで(シンボルテーブルリンクをたどって)他のクラス宣言から一時的に継承することを確認する必要があります。シンボルテーブルエントリが見つかりました。
DMS変換ルールは、本質的に「これが表示された場合は、それをそれに置き換えます」というパターンのペアです。
COBOLとC++の両方に対して、DMSを使用していくつかのカスタムスタイルチェッカーを構築しました。これはまだかなりの量の作業です。これは主に、C ++はかなり複雑な言語であり、チェックの正確な意味について慎重に考える必要があるためです。
トリッキーなチェックと、深い静的分析に分類され始めるテストでは、制御およびデータフロー情報にアクセスする必要があります。DMSは現在C++の制御フローを計算しており、データフロー分析に取り組んでいます(Java、IBM Enterprise COBOL、およびさまざまなCダイアレクトに対してこれをすでに実行しています)。分析結果はASTノードに関連付けられているため、パターンを使用してスタイルチェックの要素を探し、必要に応じてデータフローに従って要素を結び付けることができます。
すべてがDMSで(または実際に中途半端に正確な方法でC ++を処理する他のツールで)行われる場合、追加または複雑なスタイルチェックのコーディングは「便利」ではない可能性があります。あなたは「優れた技術的背景を持つ可能性がある」ことを期待するべきです。