Alex Mykyta
Alex Mykyta

Reputation: 161

Antlr4 - Best way to switch between Listener and Visitor modes?

I'm currently in the process of planning out the structure of a language interpreter and I am realizing that I do not like the idea of exclusively using a Visitor or Listener tree traversal method.

Since both tree traversal methods have their merits, Ideally, I would like to use a mix of both:

What is the most "correct" method to switch between the two traversal methods?

So far, my ideas are as follows:

Switch from Listener to Visitor for a portion of a parse tree

Say that, when the listener reaches the node "Foo", I want to handle its children more explicitly using a Visitor. One way I can think of doing this is:

Switch from Visitor to Listener for a portion of a parse tree

This is a little more obvious to me. Since tree traversal is explicitly controlled when using Visitors, switching over seems trivial.

Upvotes: 1

Views: 956

Answers (2)

IS4
IS4

Reputation: 13227

Listeners are used to process the parse tree in a push-based approach, which usually does not give much control over the iteration to the receiving code. There are still some options, however.

If you use a ParseTreeWalker, this is an extremely simple class that just recursively iterates the nodes in the tree. You could make your own one, or extend it to override Walk in a way that disables it for specific nodes that you don't need to be iterated. The only thing you need to decide is how to give that information to the walker, e.g. by explicitly listing all such node types, by coupling your listener to it and just toggling its state, or by marking the nodes somehow from the listeners, etc. In any case, your listener is then free to invoke the visitor in either Enter or Exit of such nodes.

If you use AddParseListener instead to invoke the listener during the parsing, you still need the parse tree to be processed, but you can invoke the visitor the same way, just only from Exit after it is created.

Upvotes: 0

Mike Lischke
Mike Lischke

Reputation: 53582

You seem to have gotten an idea where listeners and visitors are modes, kinda states you can switch. This is wrong.

Both listener and visitor are classes that allow you act on rule traversal. The listener does this by getting called from the parser during the parse process when a rule is "entered" or "left". There's no parse tree involved.

The visitor however uses a parse tree to walk over every node and call methods for them. You can override any of these methods to do any associated work. That doesn't necessary have to do with the evaluation result. You can use that independently.

ANTLR4 generates method bodies for each of your rule (both in listeners and visitors), which makes it easy for you to only implement those rules you are interested in.

Now that you know that listeners are used during parsing while visitors are used after parsing, it should be obvious that you cannot switch between them. And in fact switching wouldn't help much, since both classes do essentially the same (call methods for encountered rules).

I could probably give you more information if your question would actually contain what you want to achieve, not how.

Upvotes: 0

Related Questions