Antlr4 当父规则缺少以下标记时,ANTLR子规则不匹配

Antlr4 当父规则缺少以下标记时,ANTLR子规则不匹配,antlr4,Antlr4,使用ANTLR 4.7.1考虑以下简单语法 grammar Grammar; ID: [a-z]; DOT: '.'; LPAREN: '('; RPAREN: ')'; SEMICOLON: ';'; LT: '<'; GT: '>'; term : ID LT ID GT LPAREN expr RPAREN # CallExpr | ID # Id | LPAREN expr RPAREN

使用ANTLR 4.7.1考虑以下简单语法

grammar Grammar;

ID: [a-z];
DOT: '.';
LPAREN: '(';
RPAREN: ')';
SEMICOLON: ';';
LT: '<';
GT: '>';

term
    : ID LT ID GT LPAREN expr RPAREN # CallExpr
    | ID                             # Id
    | LPAREN expr RPAREN             # ParenExpr
    ;

expr
    : term DOT?               # PrimaryExpr
    | expr bop=(GT | LT) expr # BinaryExpr
    ;

update : expr SEMICOLON ;
语法;
ID:[a-z];
点:';
LPAREN:'(';
RPAREN:')';
分号:';';
LT:'';
学期
:ID LT ID GT LPAREN expr RPAREN#CallExpr
|ID#ID
|LPAREN expr RPAREN#ParenExpr
;
expr
:术语点?#PrimaryExpr
|expr-bop=(GT | LT)expr#BinaryExpr
;
更新:expr分号;
当将代码段
a(c)
与规则
expr
进行匹配时,ANTLR报告存在歧义,因为表达式可以是
PrimaryExpr
,也可以是
BinaryExpr
,其中一个操作数也是
BinaryExpr
。这是我们所期待的,也是我们所发展的语言的一个特点。由于优先级,解析器更喜欢前者,这正是我们想要的

a(c)时
update
匹配,一切都按预期工作-存在歧义,但
PrimaryExpr
具有优先权

然而,当我试图将
a(c)
update
进行匹配时,我希望除了报告缺少分号之外,还有同样的歧义。相反,只匹配了
BinaryExpr
规则。这是一个问题,因为这样的代码片段可能出现在正在编写的代码中,并导致编辑器插件autocomplete(和其他功能)无法正常工作。有没有关于为什么会发生这种情况以及如何解决它的指示

我所做的实验只是进一步增加了困惑:

  • 当删除
    BinaryExpr
    规则时,
    a(c)
    通过
    PrimaryExpr
    匹配
    update
    (缺少分号)。当我删除ANTLR使用的派生,但不报告歧义时,ANTLR如何回退到不同的派生
  • 当从
    PrimaryExpr
    中删除
    DOT?
    时,问题就消失了
  • 将自定义报告与
    update:expr(分号|{notifyErrorListeners(“缺少“;””);})
    一起使用时,问题消失了
我们可以使用第三个选项来解决这个问题,它似乎不会破坏我们测试套件中的任何东西,但我强烈感觉我没有解决根本原因,并且遗漏了一些基本的东西,这些东西以后会咬到我们

我发现了一些类似的问题,但这个问题已经解决了