5

我如何解析多个源文件并最终只使用一个 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; 
} 

但是词法分析器和解析器似乎都无法获取其他文件。我应该创建一个词法分析器和解析器公关吗?inputfile 并使用 tree.Add() 将其他文件中的树添加到第一个文件的树中?

4

2 回答 2

4

您可以通过以下三种方式执行此操作:

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

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

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

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

于 2012-08-13T14:08:34.657 回答
1

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

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 回答