Antlr4 - 在Listener和Visitor模式之间切换的最佳方式?

时间:2017-12-13 18:31:42

标签: parsing antlr4

我目前正在计划语言解释器的结构,我意识到我不喜欢专门使用Visitor或Listener树遍历方法的想法。

由于两种树遍历方法都有其优点,理想情况下,我想使用两种方法:

  • 在遍历任意语言块定义(函数/类定义,类似结构/枚举的定义)时,使用侦听器最有意义,尤其是当它们可以嵌套时。
  • 访问者似乎很自然地适应表达式评估等情况,其中上下文更容易预测,结果值可以返回到链中。

什么是最正确的"正确"在两种遍历方法之间切换的方法?

到目前为止,我的想法如下:

从侦听器切换到访问者以获取部分解析树

说,当侦听器到达节点" Foo"时,我想更明确地使用访问者处理其子节点。我能想到的一种方法是:

  • Parse Tree walker call enterFoo(ctx)
    • 创建myFooVisitor的实例
    • 明确访问儿童,存储结果等。
    • 设置ctx.children = [](或等效的)
  • enterFoo()返回时,解析树步行者看到此节点没有更多子节点,并且不会不必要地走遍所有Foo的孩子

从访问者切换到侦听器以获取部分解析树

这对我来说更加明显。由于在使用访问者时明确控制了树遍历,因此切换似乎微不足道。

  • visitFoo()被召唤
    • 创建新的解析树walker和myFooListener
    • 的实例
    • 照常使用监听器启动助行器。

1 个答案:

答案 0 :(得分:0)

您似乎已经知道听众和访客是哪种模式,有些状态可以切换。这是错误的。

侦听器和访问者都是允许您执行规则遍历的类。监听器通过在“输入”或“离开”规则的解析过程中从解析器调用来执行此操作。没有涉及解析树。

然而,访问者使用解析树遍历每个节点并为它们调用方法。您可以覆盖任何这些方法来执行任何相关的工作。这与评估结果无关。你可以独立使用它。

ANTLR4为您的每个规则(包括侦听器和访问者)生成方法主体,这使您可以轻松实现您感兴趣的规则。

现在您知道在解析期间使用侦听器而在解析后使用访问者时,显然您无法在它们之间切换。事实上,切换不会有太大帮助,因为两个类的功能基本相同(调用遇到的规则的方法)。

如果您的问题实际上包含您希望实现的 ,而不是 ,我可能会向您提供更多信息。