antlr4ts icon indicating copy to clipboard operation
antlr4ts copied to clipboard

In a recursive grammar, entry/exit calls to ParseTreeListener aren't nested

Open jessitron opened this issue 6 years ago • 1 comments

There's a recursive grammar in Java9.g4:

packageName: identifier | packageName '.' identifier;

When it parses a packageName within a packageDeclaration, say package foo.bar.baz; I expect it to parse like this, with nested recursion:

packageDeclaration
└┬ packageName
 ├ identifier "baz"
 └┬ packageName
  ├ identifier "baz"
  └┬ packageName
   ├ identifier "bar"
   └┬ packageName
    └ identifier "foo"

but, that's not the order the entry/exit calls come to the ParseTreeListener. Instead, I see:

Enter rule with name packageDeclaration at 0 
 Enter rule with name packageName at 8 
  Enter rule with name identifier at 8 
  Exit rule with name identifier at 8 
 Exit rule with name packageName at 8 
 Enter rule with name packageName at 8 
  Enter rule with name identifier at 12 
  Exit rule with name identifier at 12 
 Exit rule with name packageName at 8 
 Enter rule with name packageName at 8 
  Enter rule with name identifier at 16 
  Exit rule with name identifier at 16 
 Exit rule with name packageName at 8 
Exit rule with name packageDeclaration at 0 

so the packageName entry+exit calls come in sequence, even though the grammar is recursively nested. We're building a tree, and it doesn't come out correctly because the calls are in an unexpected order.

Is this intended?

jessitron avatar Dec 21 '18 23:12 jessitron

@jessitron Can you show an example of how you are registering your listener? I'm particularly interested to know if you are using addParseListener, since that method has some explicitly documented semantics that surprise some users:

https://github.com/tunnelvisionlabs/antlr4ts/blob/db083ec25654d3521c682c2b6b7de068fb666a94/src/Parser.ts#L281-L310

sharwell avatar Dec 22 '18 22:12 sharwell