当前位置: 首页 > 知识库问答 >
问题:

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

长孙阳嘉
2023-03-14

在ANTLR v3中,句法谓词可以用来解决歧义,即明确地告诉ANTLR应该选择哪一个选项。ANTLR4似乎只是简单地接受具有类似歧义的语法,但在解析过程中它会报告这些歧义。它生成一个解析树,尽管存在这些歧义(根据文档,通过选择第一个备选方案)。但如果我想让它选择其他选择,我能做什么呢?换句话说,我如何显式地解决歧义?

(关于悬而未决的else问题的简单情况,请参见:在ANTLR4中使用什么来解决歧义(而不是句法谓词)?)

一个更复杂的例子:

如果我有这样的规则:

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

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

>

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

    重组语法。

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

    这似乎起作用了,尽管语法变得更加复杂了。

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

  • 共有1个答案

    佟阳焱
    2023-03-14

    您可以通过将ID选项放在ID expr之上来解决这个问题。当消除左递归时,所有不是左递归的备选方案都会在左递归的备选方案之前被解析。

    对于您的示例,第一个非左递归替代id expr与整个表达式匹配,因此之后不需要解析任何内容。

     类似资料:
    • 在ANTLR v3中,句法谓词可以用来解决例如悬空的else问题。ANTLR4似乎接受具有类似歧义的语法,但在解析过程中它会报告这些歧义(例如,“line 2:29 reportAmbiguity d=0(e):ambigalts={1,2},input=...”)。它生成一个解析树,尽管存在这些歧义(根据文档,通过选择第一个备选方案)。但如果我想让它选择其他选择,我能做什么呢?换句话说,我如何显

    • 在ANTLR4中,我有一个lexer规则,说我可以使用任何字符得到任何单词,但空格和换行符除外。其定义如下: 我还有一个lexer规则(定义在than WORD之前),用于进入EVAL模式: 我考虑的另一个选择是将“word”定义为${and}包围的文本以外的任何东西。但我不知道如何创建这样的lexer规则。 我该怎么解决?要区分评价和词?

    • 我有一个非常简单的语法,如下所示: (我需要使用语义谓词,因为我需要解析关键字可以用作标识符的语言)。 参考:https://github.com/antlr/antlr4/blob/master/doc/predicates.md

    • 使用上面的测试数据运行ANTLR4测试平台,输出为 我可以看到第一个标记是ID的<4>,值为'rrv0' 我已经尝试重新安排lexer项目顺序。我还尝试通过在语法规则中显式匹配来使用隐式lexer项(而不是通过显式lexer项)。我也试着做火柴。那些对我来说并不成功。

    • 问题内容: 我想知道Java(或更普遍的是:在编程中)的一些情况,在布尔表达式中首选使用无条件()而不是有条件版本()。 我知道它们是如何工作的,但是我想不出使用单曲值得的情况。 问题答案: 我发现在现实生活中的情况下,表达的双方都真的很便宜,所以它剃掉了一两纳秒避免分支,使用无条件代替。(不过,这些都是极高性能的数学实用程序;我几乎永远不会在其他代码中使用它,并且如果没有详尽的基准测试来证明它更