5

複数のソースファイルを解析して、分析とコード生成を実行するためのASTを1つだけにする方法を教えてください。通常、私はANTLRの使用例を次の形式で見つけます

public void process(String source) 
{
    ANTLRStringStream Input = new ANTLRStringStream(input);
    TLexer lex = new TLexer(Input);
    CommonTokenStream tokens = new CommonTokenStream(lex);
    TParser parser = new TParser(tokens);
    var tree = parser.parse().Tree; 
} 

しかし、レクサーもパーサーも追加のファイルを取得できないようです。レクサーとパーサーのprを作成することになっていますか?inputfileを使用し、tree.Add()を使用して、他のファイルのツリーを最初のファイルのツリーに追加しますか?

4

2 に答える 2

4

これを行うには、次の3つの方法があります。

  1. Bartの提案を使用して、ファイルを1つのバッファーに結合します。これには、C++#lineディレクティブと同じ機能を実装するレクサールールを追加する必要があります。

  2. パーサールールによって返されるツリーを結合します。

  3. 単一のレクサーで複数の入力ストリームを使用します。これは、字句解析の前にすべてのバッファーをスタックにプッシュすることにより、インクルードファイルを処理するコードと同様のコードを使用して実行できます。

2番目のオプションがおそらく最も簡単です。私はJavaターゲットを使用していないため、これらすべてのソリューションに必要なコードの詳細を提供できません。

于 2012-08-13T14:08:34.657 に答える
1

これはあなたが求めているものに近いと思います。処理する2つのファイルをハードコーディングしましたが、ループを作成することで必要な数のファイルを処理できます。ステップで、ツリーの複製に関する// create new parent node and merge trees here into fulltreeBartの回答を参照してください。親ノードを作成し、それに子をアタッチする手順があります(申し訳ありませんが、私はこれを行っておらず、彼のコードとテストを統合する時間がありませんでした)。

public class OneASTfromTwoFiles {
    public String source1 = "file1.txt";
    public String source2 = "file2.txt";

    public static void main(String[] args)
    CommonTree fulltree;
    {
        CommonTree nodes1 = process(source1);
        CommonTree nodes2 = process(source2);
        // create new parent node and merge trees here into fulltree
        CommonTreeNodeStream nodes = new CommonTreeNodeStream(fulltree); //create node stream
        treeEval walker = new treeEval(fulltree);
        walker.startRule(); //walk the combined tree
    }

    public CommonTree process(String source)
    {
        CharStream afs = null;
        // read file; exit if error
        try { 
            afs = new ANTLRFileStream(source);
        }
        catch (IOException e) {
            System.out.println("file not found");
            System.exit(1);
        }

        TLexer lex = new TLexer(afs);
        CommonTokenStream tokens = new CommonTokenStream(lex);
        TParser parser = new TParser(tokens);
        //note startRule is the name of the first rule in your parser grammar
        TParser.startRule_return r = parser.startRule(); //parse this file
        CommonTree ast = (CommonTree)r.getTree(); //create AST from parse of this file
        return ast; //and return it
    }
}
于 2012-08-13T05:59:49.363 に答える