SASLコンパイラDiagnostic情報の管理、フォーマットと出力

4150 ワード

SASLコンパイラDiagnostic情報の管理、フォーマットと出力
1.Diagnosticが提供するデータ
エラー処理とエラープロンプトは、コンパイラ開発において重要で煩雑な部分です.
診断情報のフォーマットは、コンパイラとIDEによって異なります.
SALBIAは、ファイル+行列+カテゴリ(レベル)+番号+エラーメッセージというVisual Studio形式を採用します.例:
d:\programming\salvia\sasl\test\cgllvm_test\function_test_basic.cpp(16): error C2061: syntax error : identifier 'te'
そのため、エラー分析の際にも、上記のような情報を提供する必要があります.
2.診断情報Diagnostic Item
以上の情報では,ファイル名と行列番号を文法解析の際に得ることができ,これを属性としてTokenに付加する.
カテゴリと番号は、同じコンパイラでは相対的に固定されており、IDで表すことができますが、直感的ではなく、コンパイラチェックも少ないです.パラメータと一致する場合も、エラーが発生しやすいです.
SASLの診断情報は、エラーごとに1つのタイプを使用して表現されます.
class diagnostic_item
{
};


class unrecognized_identifier: public diagnostic_item
{
public:
    unrecognized_identifier& token( token_t tok );
    
private:
    static int level;
    static int id;
    static std::string description_template;
    
private:
    std::string ident;
    size_t      row, col;
    // Other properties
};

このような利点は、Combinatorのスタイルでエラーメッセージを書くことができることです.たとえば、次のようになります.
diagnostic_chat.report().token( err_tok );
また、コンパイラの保証で書き間違えにくくなります.
 
しかし、この書き方にも重要な問題があり、エラーごとにクラスを定義する必要があり、作業量が多い.SASLのこの問題に対する処理は、もちろん伝統的な大殺器である:スクリプトを用いて生成する.
Clangは、コード生成ツールtdを内蔵して生成を完了する.
 
3.診断情報マネージャDiagnostic Chat
Chatは診断情報の管理ツールです.主に、診断情報の追加とクリーンアップ、および診断情報の追加クリーンアップ時にコールバック操作を行う必要があります.
後者は、特にコンパイラをデバッグするときに役立ちます.本当のプログラムが間違っているのか、それともコンパイラが間違っているのか、得点がはっきりしています.
Diagnostic Chatの原型は以下の通り.
class diagnostic_chat
{
public:
    template <typename T> T& report();
    void add_report_diagnostic_handler( DiagnosticHandlerT handler );
};

また,Treat Warning As Error,Error Count,Disable Warning,Stop compiling when error occursなどの状態や機能に必要なサポートもChatに追加した.
したがって,Chatは管理を提供するほか,対応する診断情報の統計機能も持たなければならない.
 
4.フィルターDiagnostic Filter
Filterは主にIDEと連携して使用し,Chatから条件に合った診断情報を取り出す.Error CountやDisable Warningsなどの機能もそれによって実現できる.
 
5. Formatter
Formatterは、DiagnosticItemsの情報を読み取り可能な文字列に変換するために使用します.現在、SASLはVisual Studioのフォーマットのみをサポートする予定ですが、GCCのフォーマットをサポートしてEclipseなどのサードパーティIDEとの統合をよりよくすることは難しくないと信じています.
C#では、「We need'{0}'not'{1}」を使うことができます.このようにしてdescription templateを分離し、遅延するフォーマットされた文字列を生成する.しかし、C++では、このようなやり方は容易ではありません.Cのsprintfは延期、漸増のバインドテンプレートの特定を持つことが難しく、カスタムタイプの文字列化のサポートも不足し、タイプの安全も比較的悪い.streamでは,好端なフォーマット文字列を切り離す問題にも直面する.SASLはboost.を使用しています.formatは、この2つの問題をある程度解決し、C#のようにフォーマット文字列の機能を使用します.