在ANTLR4中使用什么来解决更复杂情况(而不是句法谓词)中的歧义?

时间:2014-01-29 20:13:39

标签: parsing antlr antlr4

在ANTLR v3中,句法谓词可用于解决ambiguitites,即明确告诉ANTLR应选择哪种替代方案。 ANTLR4似乎只接受具有类似歧义的语法,但在解析过程中它会报告这些歧义。它产生了一个解析树,尽管有这些含糊之处(根据文档,通过选择第一个替代方案)。但是,如果我想让它选择其他替代方案,我该怎么办?换句话说,我该如何明确地解决歧义?

(对于悬挂其他问题的简单案例,请参阅:What to use in ANTLR4 to resolve ambiguities (instead of syntactic predicates)?

一个更复杂的例子:

如果我有这样的规则:

expr
    :   expr '[' expr? ']'
    |   ID expr
    |   '[' expr ']'
    |   ID
    |   INT
    ;

这会将foo[4]解析为(expr foo (expr [ (expr 4) ]))。但我可能想将其解析为(expr (expr foo) [ (expr 4) ])。 (例如,如果可能的话,总是采取第一种选择。这是第一种选择,因此根据文档,它应该具有更高的优先级。那么为什么要构建这个树?)

如果我理解正确,我有2个解决方案:

  1. 基本上用语义谓词实现语法谓词(但是,在这种情况下,我不确定如何)。

  2. 重组语法。

  3. 例如,将expr替换为e

    e   :   expr | pe
        ;
    
    expr
        :   expr '[' expr? ']'
        |   ID expr
        |   ID
        |   INT
        ;
    
    pe  :   '[' expr ']'
        ;
    

    这似乎有效,尽管语法变得更加复杂。

    我可能误解了一些事情,但这两种解决方案似乎都不如句法谓词更优雅,更复杂。虽然,我喜欢??运算符悬挂其他问题的解决方案。但我不确定如何在这种情况下使用。有可能吗?

2 个答案:

答案 0 :(得分:0)

您可以通过将ID替代方案置于ID expr之上来解决此问题。当删除左递归时,所有未递归的替代方法都会在您的替代方案之前进行解析。

对于您的示例,第一个非左递归替代ID expr匹配整个表达式,因此之后没有任何内容可以解析。

答案 1 :(得分:0)

要获取此表达式(expr(expr foo)[(expr 4)]),可以使用

top:expr EOF;

expr:expr'['expr? ']'| ID | INT;