以编程方式使用 ANTLR4 创建 Java 8 AST
Create Java 8 AST with ANTLR4 programmatically
我正试图弄清楚如何使用 ANTLR,但我很难消化我发现的东西。到目前为止,这是我的资源:
- https://github.com/antlr/grammars-v4/tree/master/java8
- https://dzone.com/articles/parsing-any-language-in-java-in-5-minutes-using-an
- https://raw.githubusercontent.com/antlr/antlr4/master/doc/getting-started.md
一些背景知识
我正在尝试从 JavaParse 转移到 ANTLR,因为我想处理 Java 之外的语言 AST。我对 ANTLR 和预定义语法(上面链接)的理解是,这是可行的。
设置
- IntelliJ 15 CE
- Gradle
- Java 1.8
- This ANTLR resource
我在 IntelliJ 中创建了一个非常简单和标准的 gradle 项目,但我仍然遇到问题:
问题
我缺少 Java8Lexer
和 Java8Parser
类。我不知道在哪里可以找到这些。
build.gradle
group 'com.antlr-demo'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'org.antlr:antlr4-master:4.5'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
即使在这个非常简单的示例中,我需要的两个 类 中的 none 也没有被导入。
public static void parseFile(String f) { // found in Test.java:257
try {
if ( !quiet ) System.err.println(f);
// Create a scanner that reads from the input stream passed to us
Lexer lexer = new Java8Lexer(new ANTLRFileStream(f)); // missing
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Create a parser that reads from the scanner
Java8Parser parser = new Java8Parser(tokens); // missing
if ( diag ) parser.addErrorListener(new DiagnosticErrorListener());
if ( bail ) parser.setErrorHandler(new BailErrorStrategy());
if ( SLL ) parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
// start parsing at the compilationUnit rule
ParserRuleContext t = parser.compilationUnit();
if ( notree ) parser.setBuildParseTree(false);
if ( gui ) t.inspect(parser);
if ( printTree ) System.out.println(t.toStringTree(parser));
}
catch (Exception e) {
System.err.println("parser exception: "+e);
e.printStackTrace(); // so we can get stack trace
}
}
pom file中没有描述...
您还差了一步。您获得了 java8 语法,但尚未从中创建解析器。这通常涉及 运行 语法文件(FAQs and more), which is very simple (example taken from the Getting Started 页)上的 antlr4 jar:
$ antlr4 Hello.g4
$ javac Hello*.java
有一个名为 antlr
的 gradle 插件可以将 g4
个文件翻译成 java
个文件。您可以在 https://docs.gradle.org/current/userguide/antlr_plugin.html
获取 antlr
插件的详细信息
另外,使用gradle + antlr
可以看到真实工程:https://github.com/todylu/xcodeprojectParser
- antlr语法项目中的依赖:
antlr "org.antlr:antlr4:4.5.3"
- 演示项目中的依赖:
compile "org.antlr:antlr4-runtime:4.5.3"
顺便说一句,最好将ANTLR v4 grammar plugin安装到Intellij Idea中以协助您编辑g4
文件。
我在 github 上创建了一个开源项目,它会在内存中自动生成 parser/lexer 和 AST。您可以在 github https://github.com/julianthome/inmemantlr 上找到它。
从 JAVA 程序获取 AST 的代码非常简单:
// the ANTLR grammar
File f = new File("src/test/ressources/Java.g4");
// plug the ANTLR grammar in
GenericParser gp = new GenericParser(f, "Java");
// load the file that we'd like to parse into a String variable
String s = FileUtils.loadFileContent("src/test/ressources/HelloWorld.java");
// this listener will create an AST from the java file
gp.setListener(new DefaultTreeListener());
// compile Parser/Lexer
gp.compile();
ParserRuleContext ctx = ctx = gp.parse(s);
// get access to AST
Ast ast = dlist.getAst();
// print AST in dot format
System.out.println(ast.toDot());
如果您有兴趣,可以仔细查看存储库中的测试用例。
我正试图弄清楚如何使用 ANTLR,但我很难消化我发现的东西。到目前为止,这是我的资源:
- https://github.com/antlr/grammars-v4/tree/master/java8
- https://dzone.com/articles/parsing-any-language-in-java-in-5-minutes-using-an
- https://raw.githubusercontent.com/antlr/antlr4/master/doc/getting-started.md
一些背景知识
我正在尝试从 JavaParse 转移到 ANTLR,因为我想处理 Java 之外的语言 AST。我对 ANTLR 和预定义语法(上面链接)的理解是,这是可行的。
设置
- IntelliJ 15 CE
- Gradle
- Java 1.8
- This ANTLR resource
我在 IntelliJ 中创建了一个非常简单和标准的 gradle 项目,但我仍然遇到问题:
问题
我缺少 Java8Lexer
和 Java8Parser
类。我不知道在哪里可以找到这些。
build.gradle
group 'com.antlr-demo'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'org.antlr:antlr4-master:4.5'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
即使在这个非常简单的示例中,我需要的两个 类 中的 none 也没有被导入。
public static void parseFile(String f) { // found in Test.java:257
try {
if ( !quiet ) System.err.println(f);
// Create a scanner that reads from the input stream passed to us
Lexer lexer = new Java8Lexer(new ANTLRFileStream(f)); // missing
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Create a parser that reads from the scanner
Java8Parser parser = new Java8Parser(tokens); // missing
if ( diag ) parser.addErrorListener(new DiagnosticErrorListener());
if ( bail ) parser.setErrorHandler(new BailErrorStrategy());
if ( SLL ) parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
// start parsing at the compilationUnit rule
ParserRuleContext t = parser.compilationUnit();
if ( notree ) parser.setBuildParseTree(false);
if ( gui ) t.inspect(parser);
if ( printTree ) System.out.println(t.toStringTree(parser));
}
catch (Exception e) {
System.err.println("parser exception: "+e);
e.printStackTrace(); // so we can get stack trace
}
}
pom file中没有描述...
您还差了一步。您获得了 java8 语法,但尚未从中创建解析器。这通常涉及 运行 语法文件(FAQs and more), which is very simple (example taken from the Getting Started 页)上的 antlr4 jar:
$ antlr4 Hello.g4
$ javac Hello*.java
有一个名为 antlr
的 gradle 插件可以将 g4
个文件翻译成 java
个文件。您可以在 https://docs.gradle.org/current/userguide/antlr_plugin.html
antlr
插件的详细信息
另外,使用gradle + antlr
可以看到真实工程:https://github.com/todylu/xcodeprojectParser
- antlr语法项目中的依赖:
antlr "org.antlr:antlr4:4.5.3"
- 演示项目中的依赖:
compile "org.antlr:antlr4-runtime:4.5.3"
顺便说一句,最好将ANTLR v4 grammar plugin安装到Intellij Idea中以协助您编辑g4
文件。
我在 github 上创建了一个开源项目,它会在内存中自动生成 parser/lexer 和 AST。您可以在 github https://github.com/julianthome/inmemantlr 上找到它。
从 JAVA 程序获取 AST 的代码非常简单:
// the ANTLR grammar
File f = new File("src/test/ressources/Java.g4");
// plug the ANTLR grammar in
GenericParser gp = new GenericParser(f, "Java");
// load the file that we'd like to parse into a String variable
String s = FileUtils.loadFileContent("src/test/ressources/HelloWorld.java");
// this listener will create an AST from the java file
gp.setListener(new DefaultTreeListener());
// compile Parser/Lexer
gp.compile();
ParserRuleContext ctx = ctx = gp.parse(s);
// get access to AST
Ast ast = dlist.getAst();
// print AST in dot format
System.out.println(ast.toDot());
如果您有兴趣,可以仔细查看存储库中的测试用例。