ANTLR解析多个文件以生成一个AST

时间:2012-08-11 13:01:55

标签: antlr

如何解析多个源文件并最终只使用一个AST来执行分析和代码生成?通常,我会以

的形式找到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()将其他文件中的树添加到第一个文件的树中?

2 个答案:

答案 0 :(得分:3)

以下三种方法可以做到这一点:

  1. 使用Bart的建议并将文件合并到一个缓冲区中。这需要添加一个词法分析规则,该规则实现与C ++ #line指令相同的功能。

  2. 合并解析器规则返回的树。

  3. 使用单个词法分析器的多个输入流。这可以通过使用类似于处理include files的代码来完成,方法是在lexing之前将所有缓冲区推入堆栈。

  4. 第二种选择可能是最简单的。我没有使用Java目标,因此我无法提供所有这些解决方案所需的代码详细信息。

答案 1 :(得分:1)

我认为这接近你所追求的。我已经硬编码了两个要处理的文件,但您可以通过创建循环来处理所需的数量。在步骤// create new parent node and merge trees here into fulltree,请参见Bart的回答on duplicating a tree。它有创建父节点并将子节点附加到它的步骤(抱歉,但我没有这样做,没有时间集成他的代码和测试)。

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
    }
}