Antlr4失败的语义谓词应导致选择另一个替代项

Antlr4失败的语义谓词应导致选择另一个替代项,antlr4,Antlr4,我需要在它们的大列表中禁用一些替代项,以用于一些具体的上下文。 我决定通过语义谓词来实现这一点,但面临着奇怪的行为。看起来我做错了,但我不明白为什么 下面是一个最大限度简化的语法,它应该允许我展示正在发生的事情 输入文本是101,我希望它被解析为(规则1 0 1)。由于谓词失败,我希望antlr为rule1选择第二个选项,它与输入序列完全匹配 但是Antlr在输入“0”处抛出一个异常行1:1 no-available alternative,并生成这样的解析树:(rule1 1(rule2 0

我需要在它们的大列表中禁用一些替代项,以用于一些具体的上下文。 我决定通过语义谓词来实现这一点,但面临着奇怪的行为。看起来我做错了,但我不明白为什么

下面是一个最大限度简化的语法,它应该允许我展示正在发生的事情

输入文本是
101
,我希望它被解析为
(规则1 0 1)
。由于谓词失败,我希望antlr为
rule1
选择第二个选项,它与输入序列完全匹配

但是Antlr在输入“0”处抛出一个异常
行1:1 no-available alternative
,并生成这样的解析树:
(rule1 1(rule2 0 1))

我试图捕捉异常并用它进行smth,但我能理解如何处理。我想我应该报告解析器,这个分支失败了,它应该尝试下一个分支

是我做错了,还是我错过了一些琐碎的事情


注意:是的,这是一个黑客攻击,我最好分割我的
rule2
备选方案,并在
rule1
中仅使用有效的备选方案列表,但这将导致备选方案优先级出现问题,并在我的实际语法中进行直接左递归-间接。ANTLR 4解析器规则中的语义谓词可能有两种效果:

  • 谓词可以作为预测过程的一部分进行计算,预测过程确定通过语法的路径
  • 在做了一个决定之后,可以对谓词进行评估,这是验证是否采取了正确路径的一部分(如果返回false,则抛出
    predicateFileDexception
  • 第一种情况仅在谓词出现在决策的左侧时使用。由于您的语法在
    rule1
    的开头和
    rule2
    中的谓词之间包含一个
    '1'
    ,因此在
    rule1
    中选择第一个和第二个选项时,不会对谓词进行评估(假定为真)。您可以如下重构语法,以完全保留原始解析树,同时在预测期间启用谓词

    grammar Test;
    rule1:
       '1' ( rule2
           | '0' '1' // This branch should be checked, if predicate in rule2 fail and no viable alternative was found
           )
    ;
    
    rule2:
       {false}? '0' '1'
       | '1' '1' // this branch will not match
    ;
    

    如果规则2在其他规则中重复会怎样?e、 g.
    rule1:rule2(“+”rule2)*
    grammar Test;
    rule1:
       '1' ( rule2
           | '0' '1' // This branch should be checked, if predicate in rule2 fail and no viable alternative was found
           )
    ;
    
    rule2:
       {false}? '0' '1'
       | '1' '1' // this branch will not match
    ;