在使用 ANTLR4 时,我不断地回到同一个问题——如何在解析器中实现算法规则验证。
例如,我需要解析器在匹配规则之前验证写为“月日年”的日期的“年”部分。我了解到我可以使用如下谓词来做到这一点:
date :
{isYear(_input.LT(3).getText())}?
month day=INTEGER year=INTEGER { ... }
但是这个解决方案并不通用,因为它取决于规则month
始终是一个标记长。
我以为通过将规则更改为以下内容,我找到了解决此问题的方法:
date : month day=INTEGER yearInt { ... } ;
yearInt returns [int i]
: {isYear(_input.LT(1).getText())}?
yr=INTEGER { $i = $yr.int; }
;
不幸的是,这个语法将“July 11 6”作为日期传递,即使isYear("6")
失败了。当我在 XXParser.java 中跟踪 ANTLR 生成的代码时yearInt()
,我看到它调用
throw new FailedPredicateException(this, "isYear(_input.LT(1).getText())");
但代码然后继续并接受yearInt()
。
这是一个 ANTLR 错误,还是我的错误?是否有一种“正确”的方式来编写需要验证规则部分的语法?