简化 ANTLR 侦听器中的链式表达式

Simplify chained expression in ANTLR listener

我有一个用于 C++ 的 ANTLR 侦听器,我想在其中获取成员声明符的名称。目前,我正在使用这种方法:

def enterMemberDeclarator(self, ctx: CPP14Parser.MemberDeclaratorContext):
    id = ctx.declarator().pointerDeclarator().noPointerDeclarator().noPointerDeclarator().declaratorid().idExpression().unqualifiedId()

这只是一个可怕的表达。我觉得应该有一些方法可以立即获得 id 而不必去那个兔子洞。此外,其中一些表达式可能是 None 所以我担心我必须付出更多努力才能得到结果...

语法来自here

这看起来确实很脆弱(具体到一个特定的例子)。

您可以考虑使用递归方法来检查传入的上下文类型并选择适当的属性。

我不是 Python 程序员,所以(在伪代码中)如下所示:

function getMDName(ctx: <appropriate ANTLR base class) -> String 
  if ctx is MemberDeclarationContext 
    return getMDName(ctx.declarator()

  if ctx is DeclaratorContext 
    if ctx.pointerDeclarator() != null 
      return getMDName(ctx.pointerDeclarator())
    else
      return getMDName(ctx.noPointerDeclarator())
 
  if ctx is NoPointerDeclaratorContext 
    if ctx.declaratorid() != null 
      return getMDName(ctx.declaratorid())
    else if ctx.pointerDeclarator() != null 
      return getMDName(ctx.pointerDeclaration())
    else 
      return getMDNAME(ctx.noPointerDeclarator())
   
  if ctx is PointerDeclarationContext
    return getMDName(ctx.noPointerDeclaration())

  if ctx is declaratorIdContext
    return getMDName(ctx.idExpression()..unqualifiedId()
         
}

ANTLR4 支持 XPath 表达式来查找特定节点 (see the documentation)。这比你的表达式更容易阅读,特别是当你必须检查 null:

ids = XPath.findAll(ctx, "/declarator/pointerDeclarator/noPointerDeclarator/noPointerDeclarator/declaratorid/idExpression/unqualifiedId")

(这只是伪代码,我python不太了解)。