正しい答えがあるかどうかを判断するには、理想的には何らかの基準と比較する必要があります。これはコンピューター言語にとっては難しいことです。
AST の比較は難しいでしょう。そのような基準がないからです。AST を構築する各パーサーは、パーサーをコーディングした人によって構造が設計された AST を構築します。
つまり、AST を生成するパーサーを構築し、他の誰かの AST を生成するパーサーを入手した場合、選択した AST ノードが他の AST と一致しないことがわかります。次に、AST から別の AST へのマッピングを作成する必要があります (また、マッピングが有効であることをどのように確認しますか?)。パーサーが別のパーサーから AST を生成するように試みることはできますが、生成する AST は使用する解析テクノロジの影響を受けることがわかります。
私の会社が製造するJavaフロントエンドにも同様の問題があります(詳しく知りたい場合は、バイオを参照してください)。私たちが解決したのは、答えが自己一貫性があることをテストすることであり、その後、大きなコードで多くの長期的な経験的テストを行います.
私たちの解決策は次のとおりです。
- (パーサーを構築し、入手可能な最強の解析テクノロジ (GLR) を使用します。これは、他の解析テクノロジ (LL、LR、...) では容易に認識されない特定の構造を認識できることを意味し、したがって、他のパーサーが生成する AST ノードを生成します。これが重要な例については、以下のコメントを参照してください. それでも、他のほとんどの解析テクノロジで要求されるように、AST ノードの構築を手作業でコーディングする必要を完全に回避する方法で AST ノードを生成します。ハンドコーディングとは異なる AST)。
- 大量の Java コード (AST を生成する) を解析して、解析エラーがないことを確認します。[JDK はかなり良いサイズの例であり、簡単に入手できます]
- 私たちのツールは AST を取り、(prettyprint) ソース コードを再生成することができます。コメントを追加しますが、レイアウトは多少異なります。解析後にプリティプリントされたコードも解析されることを確認します。解析されたプリティプリントされたバージョンを再プリティプリントします。常に同じレイアウトを生成するため、これは prettyprinted バージョンと同じである必要があります。このテストは、AST の設計と実装がソース コードに関して何も失われていないことを示しています。
- シンボル テーブルを作成し、名前の意味を解決し、正当な Java プログラムがフロント エンドに従って型チェックを行うことを確認します。それだけでは、AST の性質については何もわかりませんが、それで十分です (実際、これで十分です!)。型チェック タスクは非常に複雑であるため (ローカルの Java 標準を確認してください)、それもかなりです。壊れやすい。すべてが正しくないと、大量のコードに適用されたときに型チェックが失敗する可能性があります。繰り返しますが、JDK はこれのかなり良いテストです。注: 名前と型の解決を行わない Java パーサーは、実際にはあまり役に立ちません。
- 上記の結果から、ハイパーリンクされたソース コードを含む JavaDoc のような相互参照を生成します。これは、名前解決 (したがって AST 構築) が適切であることを確認するためにビット コードを手動で簡単にチェックできることを意味します。
- フロントエンドをさまざまなプログラム分析とコードの変換に適用して、結果を受け入れます。時折発生する問題を見つけて修正します。
これを正しく行うのは困難です。特にJava言語が動き続けているので、近づいてテストの圧力を継続的にかけ続ける必要があります。(私たちは Java 8 にいますが、Java 9 は脅かされています)。要するに、このようなパーサーを構築してその健全性をチェックするのは大変な作業です。
独立した一連のテストを作成したいと考えていますが、実際にテストが行われたことはありません。そして、それらのテストが存在する場合 (Oracle と IBM がそれらを持っていると思います) は、解析と名前解決を直接テストするのではなく、コードの一部をコンパイルして実行し、既知の結果を生成することをテストすることを期待します。私たちはコンパイラを構築していないので、そのようなテストがあったとしても実行することはできません。名前解決と型の一貫性チェックを行うことができ、それは役に立ちます。
[私たちは実際に多くの言語フロント エンドに対してこれを行っています。Java は難しいと思います。C++ で試してみてください]