必要なのは、大規模なコード変更エンジンです。
ANTLRはそのトリックを行いません。ASTは必要ですが、十分ではありません。構文解析後の生活に関する私のエッセイを参照してください。Eclipseパッケージが名前と型の解決をある程度サポートしている場合は、Eclipseの「AST」の方が優れている可能性があります。そうしないと、すべてを同じように置き換える意思がない限り、各「doSomething」(オーバーロードまたはローカルの可能性があります)を置き換える方法を理解できません(一部のシンボルはJavaを参照しているため、これを行うことはできません)。ライブラリ要素)。
当社のDMSソフトウェアリエンジニアリングツールキットを使用して、タスクを実行できます。DMSは、JavaをASTに解析し(コメントキャプチャを含む)、任意の方法でASTをトラバースし、ASTを分析/変更し、変更されたASTを有効なソースコード(コメントを含む)としてエクスポートできます。
基本的に、すべてのコメント、文字列、および識別子の宣言を列挙し、それらを外部の「データベース」にエクスポートして、同等のものに(手動で?Google翻訳によって?)マッピングします。いずれの場合も、元のテキストで同じスペルのアイテムは、変更されたテキストで異なるスペルが必要になる可能性があるため、関心のあるアイテムだけでなく、その正確な場所(ソースファイル、行、さらには列)にも注意する必要があります。
ASTがあれば、文字列の列挙は非常に簡単です。ツリーをクロールして、文字列リテラルを含むツリーノードを探すだけです。(ANTLRとEclipseも確かにこれを行うことができます)。
コメントの列挙も、使用しているパーサーがコメントをキャプチャする場合は簡単です。DMSはそうします。ANTLRのJava文法が機能するのか、それともEclipseASTエンジンが機能するのかはよくわかりません。どちらも有能だと思います。
宣言(クラス、メソッド、フィールド、ローカル)の列挙は比較的簡単です。心配するケースはかなり多くなります(たとえば、基本クラスの拡張機能を含む匿名クラス)。ASTをウォークしてツリー構造を照合する手順をコーディングできますが、ここでDMSが違いを生み出し始めます。照合したいソースコードのように見える表面構文パターンを記述できます。例えば:
pattern local_for_loop_index(i: IDENTIFIER, t: type, e: expression, e2: expression, e3:expression): for_loop_header
= "for (\t \i = \e,\e2,\e3)"
ローカルのforループ変数の宣言と一致し、IDENTIFIER、型、およびさまざまな式のサブツリーを返します。識別子だけをキャプチャする必要があります(およびその場所。DMSがすべてのツリーノードにスタンプするソース位置情報から取得することで簡単に実行できます)。さまざまな種類の識別子すべてのケースをカバーするには、おそらく10〜20のそのようなパターンが必要です。
キャプチャステップが完了しました。キャプチャされたすべてのエンティティをターゲット言語に翻訳する必要があります。それはあなたにお任せします。残っているのは、翻訳されたエンティティを元に戻すことです。
これの鍵は、正確なソースの場所です。行番号は実際には十分ではありません。同じ行に複数の変換されたエンティティがあり、最悪の場合、スコープが異なるものもあります(たとえば、ネストされたforループを想像してください)。コメント、文字列、および宣言の置換プロセスは簡単です。識別された場所のいずれかに一致するノードをツリーで再スキャンし、そこで見つかったエンティティをその翻訳に置き換えます。(これはDMSとANTLRで行うことができます。EclipseADTでは「パッチ」を生成する必要があると思いますが、それでうまくいくと思います。)
楽しい部分は、識別子usesを置き換えることです。このためには、2つのことを知る必要があります。
- 識別子を使用する場合、宣言とは何ですか。これを知っている場合は、宣言の新しい名前に置き換えることができます。DMSは、フルネームとタイプの解決、および使用法リストを提供し、これを非常に簡単にします。
- 名前が変更された識別子は、元の識別子とは異なるスコープで相互にシャドウイングしますか?これは一般的に行うのが難しいです。ただし、Java言語の場合、「シャドウイング」チェックがあるため、名前を変更した後、少なくとも問題があると判断できます。(このようなシャドウイングの競合を解決するために使用できる名前変更手順もあります
ツリーにパッチを適用した後、DMSの組み込みのprettyprinterを使用して、パッチを適用したツリーをソースファイルとして書き直すだけです。EclipseASTはツリーとパッチを書き出すことができると思います。誰かがJava文法用にコード化したかもしれませんが、ANTLRがASTからソースコードを再生成するための機能を提供するかどうかはわかりません。細部にまでこだわったため、これは思ったよりも難しいことです。YMMV。
あなたの目標を考えると、「classfoo{...}」を含むソースファイル「foo.java」の名前を.javaに変更したくないことに少し驚いています。これには、変換されたツリーを変換されたファイル名に書き込むだけでなく(非常に簡単)、おそらくディレクトリツリーを再構築する必要があります(DMSはディレクトリ構築とファイルコピーを行うための機能も提供します)。
多くの言語でこれを実行する場合は、言語ごとに1回プロセスを実行する必要があります。文字列に対してのみこれを実行したい場合(従来の国際化の場合)、各文字列(変更が必要ですが、すべてではありません)を、一意のリソースIDを持つリソースアクセスの呼び出しに置き換えます。ランタイムテーブルはさまざまな文字列を保持します。