本文系 Creating JVM language 翻译的第 6 篇。
原文中的代码和原文有不一致的地方均在新的代码仓库中更正过,建议参考新的代码仓库。

源码

Github

Visitor vs listener

之前的章节中,我都使用了 listener 来实现 Enkel 的解析器。Antlr 提供了另一种方式– Visitor。我们需要在命令里加 -visiotor 来显示的开启。

我专门写了一篇博客,来探讨究竟哪种方式更适合 Enkel 的编译器设计和实现。

下面我们简要列举 Visitor 模式带来的好处:

  • 更少的代码
  • 更少的 BUG。无需把解析的结果保存到变量里。

对比代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Listener
class ClassListener extends EnkelBaseListener<ClassDeclaration> {

private Class parsedClass;

@Override
public void enterClassDeclaration(@NotNull EnkelParser.ClassDeclarationContext ctx) {
String className = ctx.className().getText();
//do some other stuff
parsedClass = new Class(className,methods);
}

public Class getParsedClass() {
return parsedClass;
}
}
1
2
3
4
5
6
7
8
9
10
//Visitor
public class ClassVisitor extends EnkelBaseVisitor<ClassDeclaration> {

@Override
public ClassDeclaration visitClassDeclaration(@NotNull EnkelParser.ClassDeclarationContext ctx) {
String name = ctx.className().getText();
//do some other stuff
return new ClassDeclaration(name, methods);
}
}

由此来看,切换到 Visitor 模式是一个正确的选择。