JavaScript ソース ファイルを解析し、いくつかの事実を抽出し、コードの一部を挿入/置換する必要があるプログラムを作成しています。このコードを考えると、私がする必要があることの種類の簡単な説明は次のとおりです。
foo(['a', 'b', 'c']);
'a'、'b'、およびを抽出し、'c'コードを次のように書き換えます。
foo('bar', [0, 1, 2]);
解析のニーズに ANTLR を使用して、C# 3 コードを生成しています。他の誰かがすでに JavaScript 文法を提供していました。ソースコードの解析が機能しています。
私が直面している問題は、ソース ファイルを実際に適切に分析して変更する方法を見つけ出すことです。問題を実際に解決するために取ろうとする各アプローチは、私を行き詰まりに導きます。ツールを意図したとおりに使用していないか、AST を扱うのが初心者すぎると思わずにはいられません。
私の最初のアプローチは、 を使用して解析し、関心のあるルールTokenRewriteStreamの部分メソッドを実装するEnterRule_*ことでした。これにより、トークン ストリームの変更が非常に簡単になるように見えますが、分析のための十分なコンテキスト情報がありません。私がアクセスできるのはトークンのフラットなストリームだけのようで、コードの構造全体について十分に教えてくれません。たとえば、foo関数が呼び出されているかどうかを検出するために、最初のトークンを調べるだけではうまくいきません。これも誤って一致するからです。
a.b.foo();
より洗練されたコード分析を行えるようにするための 2 番目のアプローチは、より多くのツリーを生成するように書き換え規則を使用して文法を変更することでした。さて、最初のサンプル コード ブロックはこれを生成します。
プログラム
CallExpression
識別子('foo')
引数リスト
配列リテラル
StringLiteral('a')
StringLiteral('b')
StringLiteral('c')
これは、コードの分析に最適です。しかし、今ではコードを簡単に書き直すことはできません。確かに、ツリー構造を変更して必要なコードを表すことはできますが、これを使用してソース コードを出力することはできません。各ノードに関連付けられたトークンが、少なくとも元のテキストのどこを変更する必要があるかを知るのに十分な情報を提供してくれることを望んでいましたが、得られるのはトークン インデックスまたは行/列番号だけです。行番号と列番号を使用するには、ソース コードを介して厄介な 2 番目のパスを作成する必要があります。
ANTLRを適切に使用して必要なことを行う方法を理解する上で、何かが欠けていると思います。この問題を解決するためのより適切な方法はありますか?