【问题标题】:ANTLR4: how to create a rule for "not after"ANTLR4:如何为“not after”创建规则
【发布时间】:2021-12-02 19:44:44
【问题描述】:

我正在尝试创建一个规则来捕捉音节中的尾声。尾音是一些辅音,可能跟随也可能不跟随核心,并且可能永远不会跟随开始;所以我对coda 的规则在onset 的否定后应该有consonant。假设在 ANTLR 中使用~ 进行否定,我正在努力让它工作。这是我最初的尝试:

syllable
  : onset? nucleus coda?
  ;
coda
  : ~onset consonant
  ;

在我插入 ~ 之前,语法文件一直很好,现在它向我返回错误消息 “输入 '~onset' 时没有可行的替代方案”。然后我在某处读到~ 在其右侧全部否定,所以我将其更改为:

coda
  : ~onset
    consonant
  ;

问题仍然存在。我做错了什么?

【问题讨论】:

    标签: antlr


    【解决方案1】:

    一些想法。

    Bart 是正确的,您不能在语法定义中使用对规则匹配的否定。

    要抛出一些想法:(我无法将您的语法细节描述得足够多,无法将示例放在一起)。

    在我看来,“无效”有两种可能性:


    1 - 如果你遇到这个结构,那就是错误,句号。

    如果是这种情况,那么您只需将规则更改为:

    bad_coda
      : onset consonant;
    coda
      : consonant;
    

    然后,在 Listener 或 Visitor 中,如果您遇到 bad_coda 上下文,您可以抛出自己的错误消息。

    通过这种方式,您将 ANTLR 用作“识别器”(实际上是 Parser 的超类之一的名称),它“识别”了这种错误情况。

    课程:您不仅限于为语法中的有效内容设置ONLY规则。


    2 - 如果您遇到此标记序列,您不想将其识别为结尾,但也许还有另一个 匹配的规则(因此您只需要此规则来 失败,以便尝试另一个)。在这种情况下,之前的方法将不起作用,因为 bad_coda 会匹配。

    在这种情况下,您可以将onset 设为可选,并编写一个语义谓词,如果onset 确实存在,则拒绝该规则。

    coda:
      : onset? { /* predicate that rejects if onset is present */} consonant
    

    (注意:这里没有足够的工作,我还没有尝试过,但它可能值得一试。)

    【讨论】:

    • 呵呵,你可以安全地从你的答案中删除“显然”@Mike :)
    【解决方案2】:

    在解析器规则中,您只能否定标记,而不是其他解析器规则。

    见:Negating inside lexer- and parser rules

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 2019-09-14
      相关资源
      最近更新 更多