Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr4侦听器和访问者-要实现哪个?_Antlr4 - Fatal编程技术网

Antlr4侦听器和访问者-要实现哪个?

Antlr4侦听器和访问者-要实现哪个?,antlr4,Antlr4,我正在阅读“权威的Antlr 4参考”,了解听众和访问者的工作方式。这本书特别好地解释了监听器与SAX解析器之间的关系,并明确了在每个解析器的实现过程中何时调用方法。我还可以看出,侦听器在将输入转换为输出方面非常好,但我希望能提供一个简短的解释/示例,说明何时使用侦听器以及何时使用访问者(或者在某些情况下它们是否都应该使用?) 我的特别意图是创建一个解释器(Cucumber样式/TinyBasic解释器,带有一些自定义调用),它将检查语法错误,并停止执行自定义函数中的错误,而不进行恢复—希望在a

我正在阅读“权威的Antlr 4参考”,了解听众和访问者的工作方式。这本书特别好地解释了监听器与SAX解析器之间的关系,并明确了在每个解析器的实现过程中何时调用方法。我还可以看出,侦听器在将输入转换为输出方面非常好,但我希望能提供一个简短的解释/示例,说明何时使用侦听器以及何时使用访问者(或者在某些情况下它们是否都应该使用?)

我的特别意图是创建一个解释器(Cucumber样式/TinyBasic解释器,带有一些自定义调用),它将检查语法错误,并停止执行自定义函数中的错误,而不进行恢复—希望在antlr中看到这样一个东西的完整实现—如果有人碰巧知道的话


提前感谢您的建议。

如果您计划直接使用解析器输出进行解释,那么访问者是一个不错的选择。您可以完全控制遍历,所以在条件语句中只访问一个分支,循环可以访问n次,以此类推

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

您可以看看“语言实现模式”,它涵盖了基本的解释器实现


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

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

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


在visitor模式中,您可以指导树遍历,而在listener模式中,您只能对树遍历做出反应。

这两种模式之间还有另一个重要区别:访问者使用调用堆栈来管理树遍历,而监听器使用堆上分配的显式堆栈,由walker管理。这意味着访问者的大量输入可能会破坏堆栈,而侦听器则不会有问题


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

摘自该书第120页

如果我们需要特定于应用程序的返回值,访问者工作得非常好,因为我们可以使用内置的Java返回值机制。如果我们不希望显式调用visitor方法来访问子对象,我们可以切换到侦听器机制。不幸的是,这意味着放弃使用Java方法返回值的清洁性


这就是我使用访客的原因。

@OP您是否可以发布一个更新-您实际使用了什么,以及任何外卖。谢谢