antlr4:如何在没有生成规则的情况下为令牌生成侦听器回调?

antlr4:如何在没有生成规则的情况下为令牌生成侦听器回调?,antlr4,Antlr4,在我调查了中引用的语法之后,很明显问题的关键在于这些产生式规则: TIMESPAN : startTime (WS THRU WS endTime)? ; startTime : TOD ; endTime : TOD ; 中间生成规则startTime和endTime的原因是为这些规则生成侦听器回调,因此我不必在TIMESPAN侦听器中显式解析它们。但显然,这混淆了antlr4解析器。为了解决这个问题,我将规则简化如下: TIMESPAN : TOD (WS THRU WS TOD)

在我调查了中引用的语法之后,很明显问题的关键在于这些产生式规则:

TIMESPAN  : startTime (WS THRU WS endTime)? ;
startTime : TOD ;
endTime   : TOD ;
中间生成规则
startTime
endTime
的原因是为这些规则生成侦听器回调,因此我不必在TIMESPAN侦听器中显式解析它们。但显然,这混淆了antlr4解析器。为了解决这个问题,我将规则简化如下:

TIMESPAN  : TOD (WS THRU WS TOD)? ;
并进一步进行了这一改变:

TIMESPAN  : (TOD THRU TOD) | TOD ;
这两条规则中的任何一条都可以编译语法

由于antlr4不再支持这样的标签:

TIMESPAN  : (startTime=TOD THRU endTime=TOD) | startTime=TOD ;
我的问题是如何标记此语法的输入,以便捕获
startTime
endTime


谢谢。

我相信这里的答案是,在antlr中:

  • 左侧大写的产生式规则包含与lexer相关的规则——也就是说,您实际上得到了您的逻辑可以相应处理的令牌
  • 左侧未大写的产生式规则包括与解析器相关的规则——即,将左侧进一步分解为表达式(即附加产生式规则)、标记或两者的规则

antlr4中的侦听器是一个合适的位置,您可以在这里截取相应解析器规则的结果。在本例中,您将设置一个侦听器,在侦听器回调中设置
startTime
endTime
,然后在完成树遍历时,根据需要使用这些值。

按照惯例,antlr4似乎为非大写规则(例如startTime和endTime)生成侦听器,但不为大写规则生成侦听器(例如,TIMESPAN)。我认为后者被理解为包含令牌的“基本”组件(例如,数字或字符串序列)不需要生成侦听器。我不是antlr4专家,所以我会等待评论…如果有人想发布正式响应,我会稍后给你评分。在组合语法文件中,以大写字母开头的规则是lexer规则,以非大写字母开头的规则是parser规则。lexer规则由Antlr处理,parser规则将由用户代码处理。谢谢。我已经编辑了我的回复,以符合您的评论。谢谢您的更正。