Antlr4侦听器和访问者-要实现哪个?
我正在阅读“权威的Antlr 4参考”,了解听众和访问者的工作方式。这本书特别好地解释了监听器与SAX解析器之间的关系,并明确了在每个解析器的实现过程中何时调用方法。我还可以看出,侦听器在将输入转换为输出方面非常好,但我希望能提供一个简短的解释/示例,说明何时使用侦听器以及何时使用访问者(或者在某些情况下它们是否都应该使用?) 我的特别意图是创建一个解释器(Cucumber样式/TinyBasic解释器,带有一些自定义调用),它将检查语法错误,并停止执行自定义函数中的错误,而不进行恢复—希望在antlr中看到这样一个东西的完整实现—如果有人碰巧知道的话Antlr4侦听器和访问者-要实现哪个?,antlr4,Antlr4,我正在阅读“权威的Antlr 4参考”,了解听众和访问者的工作方式。这本书特别好地解释了监听器与SAX解析器之间的关系,并明确了在每个解析器的实现过程中何时调用方法。我还可以看出,侦听器在将输入转换为输出方面非常好,但我希望能提供一个简短的解释/示例,说明何时使用侦听器以及何时使用访问者(或者在某些情况下它们是否都应该使用?) 我的特别意图是创建一个解释器(Cucumber样式/TinyBasic解释器,带有一些自定义调用),它将检查语法错误,并停止执行自定义函数中的错误,而不进行恢复—希望在a
提前感谢您的建议。如果您计划直接使用解析器输出进行解释,那么访问者是一个不错的选择。您可以完全控制遍历,所以在条件语句中只访问一个分支,循环可以访问n次,以此类推 如果将输入转换到较低级别,例如虚拟机指令,则这两种模式都可能有用 您可以看看“语言实现模式”,它涵盖了基本的解释器实现
我主要使用访客模式,因为它更灵活。以下是我认为相关的书中的引文: 侦听器和访问者机制之间的最大区别在于,侦听器方法由ANTLR提供的walker对象调用,而访问者方法必须通过显式的访问调用遍历其子对象。忘记对节点的子节点调用visit()意味着这些子树没有被访问
在visitor模式中,您可以指导树遍历,而在listener模式中,您只能对树遍历做出反应。这两种模式之间还有另一个重要区别:访问者使用调用堆栈来管理树遍历,而监听器使用堆上分配的显式堆栈,由walker管理。这意味着访问者的大量输入可能会破坏堆栈,而侦听器则不会有问题
如果您的输入可能是无限的,或者您可能在调用树中调用非常深的访问者,那么您应该使用侦听器,而不是访问者,或者至少验证解析树是否不太深。由于这个原因,一些公司的编码实践不鼓励甚至完全禁止非尾部递归 摘自该书第120页 如果我们需要特定于应用程序的返回值,访问者工作得非常好,因为我们可以使用内置的Java返回值机制。如果我们不希望显式调用visitor方法来访问子对象,我们可以切换到侦听器机制。不幸的是,这意味着放弃使用Java方法返回值的清洁性
这就是我使用访客的原因。@OP您是否可以发布一个更新-您实际使用了什么,以及任何外卖。谢谢