ANTLR 4解析树监听器

1 解析树

ANTLR默认为输入的语句构建一个数据结构,称为解析树或语义树。

树的根节点是抽象的阶段名称,如stat。中间节点是对应的解析规则名称,叶子节点是记号。

解析树自动更新,可以使用parser.setBuildParseTree(false)关闭。

img

ANTLR使用ParseTreeWalker遍历解析树,并触发监听器中定义的事件。

以下为对应Java.g4语法的监听器:

1
2
3
4
5
6
public interface JavaListener extends ParseTreeListener<Token> {
void enterClassDeclaration(JavaParser.ClassDeclarationContext ctx);
void exitClassDeclaration(JavaParser.ClassDeclarationContext ctx);
void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx);
...
}

同时ANTLR也生成了一个兜底的监听器,名叫JavaBaseListener。可以继承并覆盖。

假设创建了一个名为MyListener的监听器对象,可以使用以下方式调用解析器,并遍历解析树。

1
2
3
4
5
6
7
JavaLexer lexer = new JavaLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
JavaParser parser = new JavaParser(tokens);
JavaParser.CompilationUnitContext tree = parser.compilationUnit(); // parse a compilationUnit

MyListener extractor = new MyListener(parser);
ParseTreeWalker.DEFAULT.walk(extractor, tree); // initiate walk of tree with listener in use of default walker

监听器和访问器保存有应用程序相关的代码,使语法易读且与特定应用程序隔离。

监听器和访问器的区别是,监听器被walker独立调用,而访问器显式调用其子孙。

参考资料