Parsing ANTLR4谓词失败忽略以下选项?

Parsing ANTLR4谓词失败忽略以下选项?,parsing,antlr,text-parsing,antlr4,Parsing,Antlr,Text Parsing,Antlr4,我在ANTLR 4中遇到语义谓词的问题。我的语法在语法上是模糊的,需要向前看一个标记来解决模糊性 例如,我想将“2012年1月19日至晚上9点”解析为日期“2012年1月19日”,将解析器的下一个标记保留为“直到”。我想将“1月19日,7日到晚上9点”解析为日期“1月19日”,解析器的下一个标记为“7” 所以我需要看第三个代币,要么接受它,要么离开它 我的语法片段是: date : month d=INTEGER { isYear(getCurrentToken().getTex

我在ANTLR 4中遇到语义谓词的问题。我的语法在语法上是模糊的,需要向前看一个标记来解决模糊性

例如,我想将“2012年1月19日至晚上9点”解析为日期“2012年1月19日”,将解析器的下一个标记保留为“直到”。我想将“1月19日,7日到晚上9点”解析为日期“1月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}
    ;                                             
当解析器在任一示例输入上运行时,我得到以下消息:

line 1:9 rule date failed predicate: { isYear(getCurrentToken().getText())}?
它永远不会进入第二条规则,因为(我猜)它已经读取了一个额外的令牌


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

在解析器规则中,ANTLR 4在做出决策时只使用左边的谓词。上面显示的内联谓词仅经过验证

下面的修改将导致ANTLR在做出决策时对谓词求值,但显然您需要修改它以使用正确的先行标记,而不是调用
getCurrentToken()


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

一个解决方案是使用两个解析器,第一个解析器如上所述,没有谓词。第一次输入打印“$DATE(2012-1-19)至晚上9点”,第二次输入打印“$DATE(2013-1-19)至晚上9点”。但如果出现其他类似的歧义,这将成为一个n解析器解决方案。谢谢。我想你的意思是LT(3),LA(3)给了我一个语法错误。这解决了我的问题。
date
  : {isYear(getCurrentToken().getText())}? month d=INTEGER y=INTEGER
                                {//handle date, use $y for year}
  | month d=INTEGER             {//handle date, use 2013 for year}
  ;