Antlr4听众和访客 - 要实施哪些?

Kev*_*inY 42 antlr4

我正在阅读"The Definitive Antlr 4 Reference",并了解听众和访客的工作方式.这本书特别详细地解释了监听器如何与SAX解析器相关,并且在每个解析器的实现过程中调用方法时都很明显.我还可以看到,监听器非常适合将输入转换为输出,但我很欣赏一个简短的解释/示例,关于何时使用监听器以及何时使用访问者(或者它们是否应该在某些情况下使用?).

我的特殊目的是创建一个解释器(带有一些自定义调用的Cucumber-style/TinyBasic Interpreter),它将检查语法错误并停止执行自定义函数的错误而不恢复 - 很想看到这样的事情的完整实现在antlr - 如果有人碰巧知道一个.

提前感谢任何建议.

Evg*_*rov 47

以下是我认为相关的书的引用:

侦听器和访问者机制之间的最大区别在于侦听器方法由ANTLR提供的walker对象调用,而访问者方法必须通过显式访问调用来访问其子节点.忘记在节点的子节点上调用visit()意味着不会访问这些子树.

在访客模式中,您可以指导树木行走,而在听众中,您只对树木行走者做出反应.


Fre*_*ack 32

如果您打算直接使用解析器输出进行解释,则访问者是一个不错的选择.您可以完全控制遍历,因此在条件中只访问一个分支,循环可以访问n次,依此类推.

如果将输入转换为较低级别,例如虚拟机指令,则两种模式都可能有用.

您可以查看"语言实现模式",其中介绍了基本的解释器实现.

我主要使用访客模式,因为它更灵活.


Ale*_*ing 9

这两种模式之间还有另一个重要区别:访问者使用调用堆栈来管理树遍历,而侦听器使用在堆上分配的显式堆栈,由walker管理.这意味着访问者的大量输入可以炸掉堆栈,而听众则没有任何问题.

如果您的输入可能是无限制的,或者您可能会在调用树中深入调用访问者,则应使用监听器而不是访问者,或者至少验证解析树不是太深.由于这个原因,一些公司的编码实践不鼓励甚至完全禁止非尾递归.