我在 ANTLR 网站上找到了一个示例模板,它是 Javatreeparser.g,该网站说它可以生成我需要的 AST,但是由于我是 ANTLR 的新手,我该如何让它显示?到目前为止,我所做的是将语法文件与我现有的 java 语法放在一起。但我不知道如何从文件中使用和输出我需要的 AST。我该怎么做?
2 回答
我在 ANTLR 网站上找到了一个示例模板,它是 Javatreeparser.g,该网站说它可以生成我需要的 AST,
不,Java.g
来自 ANTLR wiki的组合语法为 Java 源文件生成了词法分析器和解析器。然后解析器构造这个源的 AST,然后可以使用这个 ASTJavaTreeParser.g
来遍历它。树语法JavaTreeParser.g
不用于创建 AST 。这是由从创建的解析器完成的Java.g
。
到目前为止,我所做的是将语法文件与我现有的 java 语法放在一起。
这是不正确的。树语法JavaTreeParser.g
需要一个 AST 作为解析器生成的输入Java.g
。您不能只插入另一个解析器(或其他树语法,就此而言)。
但我不知道如何从文件中使用和输出我需要的 AST。我该怎么做?
请参阅之前的问答:Visualizing an AST created with ANTLR (in a .Net environment)
编辑
我不想立即发布此内容,因为我希望您先自己尝试一下(是的,我是认真的!);)
这是一个快速演示:
- 复制
Java.g
目录并从中删除@header{...}
和@lexer:::header{...}
声明; - 复制
antlr-3.3.jar
到同一目录; - 创建文件
Main.java
并Test.java
在此目录中(见下文)。
测试.java
public class Test {
int i = 1 + 2;
String s;
Test(String s) {
this.s = s;
}
}
主.java
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
JavaLexer lexer = new JavaLexer(new ANTLRFileStream("Test.java"));
JavaParser parser = new JavaParser(new CommonTokenStream(lexer));
CommonTree tree = (CommonTree)parser.javaSource().getTree();
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
现在生成一个词法分析器和解析器:
java -cp antlr-3.3.jar org.antlr.Tool Java.g
然后编译所有.java
源文件:
javac -cp antlr-3.3.jar *.java
最后运行Main
该类并将输出通过管道传输到一个名为ast.dot
.
java -cp .:antlr-3.3.jar Main > ast.dot
(在 Windows 上,执行java -cp .;antlr-3.3.jar Main > ast.dot
:)
如果您现在打开文件ast.dot
,您会看到解析器生成的 AST的DOT表示。您可以通过在此处复制粘贴 DOT 源来可视化此 AST:http: //graphviz-dev.appspot.com,得到以下图像:
我真的推荐你使用antlr4。
首先,设置您的 CLASSPATH(包括 antlr-4.5.3-complete.jar)和 JAVA_HOME。
其次,从语法 Java.g4 生成词法分析器和解析器:
java -cp antlr-4.5.2-complete.jar Java.g4
三、编译所有生成的Java*.java:
javac Java*.java
最后,运行 TestRig:
java org.antlr.v4.runtime.misc.TestRig Java compilationUnit -gui Test.java
您将直观地看到 AST,如下所示: