ANTLR4 谓词失败忽略以下替代方案?

Ken*_*mer 3 parsing antlr text-parsing antlr4

我在处理 ANTLR 4 中的语义谓词时遇到了麻烦。我的语法在句法上有歧义,需要提前一个标记来解决歧义。

例如,我想将“2012 年 1 月 19 日至晚上 9 点”解析为日期“2012 年 1 月 19 日”,将解析器的下一个标记留在“直到”。我想将“Jan 19, 7 to 9 pm”解析为日期“Jan.19”,解析器的下一个标记为“7”。

所以我需要查看第三个令牌,然后要么接受要么离开。

我的语法片段是:

date
    :    month d=INTEGER  { isYear(getCurrentToken().getText())}?  y=INTEGER
                                    {//handle date, use $y for year}
    |    month d=INTEGER            {//handle date, use 2013 for year}
    ;                                             
Run Code Online (Sandbox Code Playgroud)

当解析器在任一示例输入上运行时,我收到以下消息:

line 1:9 rule date failed predicate: { isYear(getCurrentToken().getText())}?
Run Code Online (Sandbox Code Playgroud)

它永远不会到达第二个规则替代方案,因为(我猜)它已经读取了一个额外的标记。

有人可以告诉我如何做到这一点吗?

Sam*_*ell 6

在解析器规则中,ANTLR 4 仅在做出决定时使用左边缘的谓词。像您上面展示的那样的内联谓词仅经过验证

以下修改将导致 ANTLR 在做出决定时评估谓词,但显然您需要修改它以使用正确的前瞻标记而不是调用getCurrentToken().

date
  : {isYear(getCurrentToken().getText())}? month d=INTEGER y=INTEGER
                                {//handle date, use $y for year}
  | month d=INTEGER             {//handle date, use 2013 for year}
  ;
Run Code Online (Sandbox Code Playgroud)

PS:如果month总是正好是一个令牌长,那么_input.LT(3)应该提供你想要的令牌。