java 如何在antlr中递归地检查给定上下文的子上下文?

ct2axkht  于 2023-06-28  发布在  Java
关注(0)|答案(1)|浏览(89)

我正在使用一个非常大的语法,CFG中有一个循环,但没有无限递归。
我需要检查特定上下文的所有子上下文,如果我的目标上下文在这些子上下文中,那么我需要抛出一个错误。
假设我的语法是

Sentence
    :   Nouns 'AND' Sentence
    |   Pronouns 'AND' Sentence
    |   'WITH APPLESAUCE'
    ;
    
    Nouns  
    :   Names
    |   Places
    |   Animals
    |   Things
    ;
    
    Names
    :   word 'AND' Sentence
    ;
        
    word
    :   (A-Z) (a-z)* // just any word
    ;

我必须确保,如果一个句子有一个名称词,那么来自该名称规则的句子必须没有任何其他名称?即,

Sentence ->
    Nouns 'AND' 'WITH APPLESAUCE' ->
    Names 'AND' 'WITH APPLESAUCE' ->
    word 'AND' Sentence 'AND' 'WITH APPLESAUCE', in this case,

word 'AND' Names 'AND' 'WITH APPLESAUCE'无效,但word 'AND' Places 'AND' 'WITH APPLESAUCE'有效?
我试着浏览antlr文档,但找不到任何递归搜索子对象的东西。我知道antlr会生成一个解析树,所以我想也许可以检查从给定的点是否有一个特定的子/孙/第n个子上下文。

axr492tv

axr492tv1#

ANTLR将根据您的输入创建一个ParseTree。这个ParseTree有一个getChild(int)方法,它也返回一个ParseTree。使用它深入到你的根树,并找出是否在另一个内部使用了某个规则。
或者使用listener并跟踪何时发生enterSentence(...)调用。当这样做时,在侦听器中保留一个示例变量,然后实现enterNames(...),当来自enterSentence(...)的示例变量已经设置时,它将抛出异常。
伪代码:

class YourListener extends YourGrammarBaseListener {

  boolean insideSentence = false

  void enterSentence(...) {
    insideSentence = true
  }

  void exitSentence(...) {
    insideSentence = false
  }

  void enterNames(...) {
    if (insideSentence) {
      throw Error()
    }
  }
}

相关问题