1

I have an ANTLR listener for C++ where I want to get the name of a member declarator. Currently, I'm using this approach:

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

which is just a horrible expression. I feel like there should be some way of getting the id immediately without having to go down that rabbit hole. Additionally, some of these expressions might be None so I fear that I would have to make even more effort to get to the result...

The grammar is from here

Schottky
  • 1,549
  • 1
  • 4
  • 19

2 Answers2

2

ANTLR4 supports XPath expressions to find specific nodes (see the documentation). That's somewhat easier to read than your expression, especially when you have to check for null:

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

(this is just pseudo code, I don't know python well).

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
  • That's pretty much what I was looking for, thx! For python, the usage is something like `XPath.findAll(ctx, '/ctx/declarator/...', ctx.parser)`, at least for version 3.9. Note that I had to include the context as first argument for whatever reason – Schottky Feb 07 '22 at 11:25
0

This definitely looks very brittle (specific to a particular example).

You might consider a recursive method that checks the type of the context being passed in and chooses the appropriate attribute.

I'm not a Python programmer, so (in pseudoCode) something like the following:

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()
         
}
Mike Cargal
  • 6,610
  • 3
  • 21
  • 27