给出以下语法:
grammar ReportAmbiguity;
unit : statements+;
statements :
callStatement+
// '.' // <- uncomment this line
;
callStatement : 'CALL' ID (argsByRef | argsByVal)*;
argsByRef : ('BY' 'REF')? ID+;
argsByVal : 'BY' 'VAL' ID+;
ID : ('A'..'Z')+;
WS : (' '|'\n')+ -> channel(HIDDEN);
通过非根规则"CALL FUNCTION BY VAL A B"
解析字符串callStatement
时一切正常,解析器正确报告歧义:
line 1:24 reportAttemptingFullContext d=6 (argsByVal), input='B'
line 1:24 reportAmbiguity d=6 (argsByVal): ambigAlts={1, 2}, input='B'
Parser正确输出树:(callStatement CALL FUNCTION (argsByVal BY VAL A B))
。
现在考虑取消注释上面显示的行(第7行)。再次测试一切。
解析器仍然输出相同的树,但模糊报告消失了。 为什么这种含糊不清的输入的模糊语法不再被报道了?
(这是一个更大问题的一部分。我正在努力理解这一点,所以我可以用我的语法确定另一个可能的问题。)
编辑1
使用antlr4版本4.6。
我已经在github中准备了一个宠物项目:https://github.com/rslemos/pet-grammars(在模块g
中,键入mvn clean test -Dtest=br.eti.rslemos.petgrammars.ReportAmbiguityUnitTest
以测试注释版本;取消注释第7行并再次运行以查看它失败了。)
编辑2
将unit: statements*;
更改为unit: statements+;
。此更改本身不会改变原始问题。它只允许另一种体验(进一步版本待定)。
编辑3
触发此错误的另一种方法是将unit: statements+;
更改为unit: statements+ unit;
。
将'.'
添加到statements
时,此更改也会使antlr4放弃模糊检测。
我认为这与可能跟随EOF
的{{1}}有关。
第一个备选方案(将argsByVal
附加到'.'
)会阻止statements
出现在EOF
之后。
第二个(将argsByVal
附加到自身)使其成为非根规则(并且似乎antlr隐式地将unit
附加到每个根规则。)
我一直认为antlr4规则无论如何都要被调用,没有给出一些特殊处理规则,因为我们(语法作者)知道哪个规则是根
编辑4