Antlr 4在Java中生成解析树代码

Antlr 4在Java中生成解析树代码,java,sql,parsing,antlr,antlr4,Java,Sql,Parsing,Antlr,Antlr4,使用Antlr4,我想以Java/JavaScript代码的形式生成解析树。 这就是我的main.Java的样子 String sql = "SELECT log AS x FROM t1 \n" + "GROUP BY x\n" + "HAVING count(*) >= 4 \n" + "ORDER BY max(n) + 0"; // Create a lexer an

使用Antlr4,我想以Java/JavaScript代码的形式生成解析树。 这就是我的main.Java的样子

 String sql = "SELECT log AS x FROM t1 \n" +
                "GROUP BY x\n" +
                "HAVING count(*) >= 4 \n" +
                "ORDER BY max(n) + 0";

        // Create a lexer and parser for the input.
        SQLiteLexer lexer = new SQLiteLexer(new ANTLRInputStream(sql));
        SQLiteParser parser = new SQLiteParser(new CommonTokenStream(lexer));

        // Invoke the `select_stmt` production.
        ParseTree tree = parser.select_stmt();
        ParseTreeWalker walker = new ParseTreeWalker();
        SQLiteListener listener = new SQLiteBaseListener();
        ParseTreeWalker.DEFAULT.walk(listener, tree);
    System.out.println(listener.);
我应该调用什么函数以代码格式生成解析树

这一行:

ParseTree tree = parser.select_stmt();
是您的解析树。签出API文档以查看它有什么方法:


您可能会对它的
getChild(…)
getParent()
方法感兴趣。

我不确定您所说的“层次”视图是什么意思。如果您正在寻找的是-gui选项,那么antlr命令行工具就有了这个选项。否则,您可以通过在ANTLR创建的enter/exist侦听器方法中添加操作和/或添加sysout来打印语法的计算方式。例如,如果您有以下语法:

grammar Grammar;

@lexer::header{
 //package name where Java files will be created
}

@parser::header{
//package name where Java files will be created
}


value  : letters | number | string;

letters : LETTERS;
number  : NUMBER;
string  : STRING;

LETTERS : '/*' {System.out.println("Found Letters!");};
NUMBER  : [0-9]+ {System.out.println("Found Number!");};
STRING : [a-zA-Z0-9]+ {System.out.println("Found String!");};

WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
如果在Eclipse中右键单击.g4文件并选择安装了ANTRL4 IDE的“生成ANTLR识别器”,Antl4将生成一个GrammarListener.java(假设您的语法名为grammar.g4)。您还可以通过调用静态org.antlr.v4.Tool.main,使用Java生成解析器和lexer:

生成的接口将包含如下方法:

public interface GrammarListener extends ParserTreeListener {
    void enterValue(GrammarParser.Valuecontext ctx);
    void exitValue(GrammarParser.ValueContext ctx);
    void enterLetters(GrammarParser.StringContext ctx);
    void exitLetters(GrammarParser.StringContext ctx);
    .
    .
}
您需要实现此接口

public class GrammarListenerImpl implements GrammarListener {

.
.
@Override
public void enterLetters(GrammarParser.LetterContext ctx) {
 System.out.println("Enter: Letters");
// do other stuff
.
.
}
并添加sysout(在本例中)或其他业务逻辑,以便在语法中发生此匹配时进行处理。系统输出可以生成如下内容:

Enter value
   Enter Letters
     Do something...
   Exit Letters
Exit value

这将显示一个嵌套的(使用制表符/空格等格式化)调用序列,在该调用序列中计算语法。

您能给出一个示例,您想在standard out上看到什么吗?@StefanA-我想要以层次化java类的形式显示解析树。“层次化java类”在没有更多上下文的情况下是没有意义的。你是说你想得到一个AST吗?您需要创建Java类并手动构建AST。这是我唯一能想到的与你的要求有关的事情。谢谢巴特,我正在使用这种方法。我想知道这个解析树是否可以以分层java类的形式查看。嗨@user3898179,不知道“分层java类”是什么意思。我对
ParseTree
的理解是:一个可以访问父节点和子节点的Java类(即“分层Java类”)。这是一个很好的答案,但它忽略了旨在执行侦听器和相关Sysout的代码。
Enter value
   Enter Letters
     Do something...
   Exit Letters
Exit value