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)
它永远不会到达第二个规则替代方案,因为(我猜)它已经读取了一个额外的标记。
有人可以告诉我如何做到这一点吗?
在解析器规则中,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)应该提供你想要的令牌。