私の知る限り、ANTLR は、制御フロー グラフの作成に特定のヘルプを提供しません。
AST をウォークし、アクション (無条件ステートメント) と条件 (式ノードが条件を制御) の知識を収集し、その情報からグラフを組み立てることで、自分で 1 つを構築できます。switch ステートメントは一種の複合条件であり、一連の決定、または特殊な N-way 条件として処理する必要があることに注意してください。
例外処理によって、「無条件のアクション」と見なされるものが変わる場合があります。すべてのメソッド呼び出しには、制御フローを例外ハンドラー (または関数の出口) にリダイレクトする可能性があり、これらを制御フロー グラフに含めるかどうかを決定する必要があります。プログラムの動作 (特にデータフロー) について推論したい場合は、これらをモデル化する必要があります。
AST の一部 (「これはアクション」) と他の 2 つの制御フロー ノード (if-then-else を処理するため) を参照できる制御フロー ノード (一種のクラス) を作成する必要があります。これらの出口は、「真の出口」および「偽の出口」として、または代わりに「続行」および「トラップ」出口として使用されます。これのサブクラスは、純粋な計算、IF ステートメント、TRY ブロックなどを表します。
Java が純粋な「構造化」言語であるという事実は、制御フロー グラフを「ボトムアップ」で構築できることを意味します。葉から上に向かってトラバースしながら制御フロー グラフの一部を構築し、ツリーを登るときに子からの制御フロー グラフを組み合わせることができます。あなたがする必要があるのは、例外ハンドラーに制御を渡したいグラフ内の制御フローノードのリストへの参照を使用して、これまでに組み立てられた制御フローグラフ (最初は葉で空) をツリーに渡すことです。次に、ツリーを登りながら、制御フロー グラフを拡張します。
ほとんどの作業は、IF-THEN-ELSE ノードなどの条件で発生します。この場合、2 つの例外セットを持つ 2 つの制御フロー サブグラフがそのノードに渡されます。次に、条件式を表す制御フロー ノードを作成し、そのアクションを条件式を指すように設定し、渡された 2 つのサブグラフを指すようにその 2 つの子を設定し、その例外セットを例外セットの和集合に設定します。
サブルーチン呼び出しは、アクションがメソッド呼び出しであるフロー ノードを取得し、次のステートメント/部分式への出口と、最終的に catch 句を指す別の出口 (埋められていない) を持ちます。渡された例外のリストにサブルーチン呼び出しノードを追加します。
「次の」アクションはありませんが、THROW ステートメントも同様に扱います。
TRY コンストラクトに遭遇した場合は、アクションが try 本体を指す条件付きノードを生成し、1 つの出口が try の最後または finally サブルーチン呼び出しを指します。最後に、例外リスト内のすべての制御フロー ノードにパッチを適用して、catch 句を指すようにします。
一連の if ステートメントとして catch 句を連鎖させる必要があります。
"finally" は、try 句とさまざまな catch 句から呼び出されるサブルーチン呼び出しとして扱う必要があります。