dentaku
dentaku copied to clipboard
Support visitor pattern for AST
It might be quiet useful to support a visitor pattern for traversing the AST.
I pushed an initial implementation of this to the visitor branch.
@rubysolo it looks already pretty nice. However, I can imagine a few improvements:
- Don't force a visitor to implement all
visit_type
methods, check forrespond_to?
? - Add a general
visit
callback. Thus, if the visitor responds to it, it might filter on type by its own - Generate default implementations for
visit_negation
likesend("visit_#{self.class.name.demodulize}", ...)
- PrintVisitor, I find a bit strage that the PrintVisitor calls
accept
on some nodes. Because the AST should decide which nodes are visited an in which order and the visitor should only react on it.
What do you think?
Yes, these are good suggestions.
Regarding PrintVisitor calling accept
-- my thought was that the visitor needs to control the order of evaluation (e.g. a visitor might want to print out in prefix notation). Is there a better way to handle that?
Hmm, here are my thoughts:
- We could add more parameters to the
accept
methods, that can indicate traversal order (by a flag or rich object, e.g.Traversal::PreOrder
,Traversal::PostOrder
). This looks to me a bit like a composite visitor, one visitor controls the traversal ordering and another the "real" logic. - The visitor is responsible for traversal and we provide base implementations that define the traversal and call some kind of
process
method (template method). Similar to 1. but baked into 1 concept StackOverflow - Provide more context while traversing by using
visitEnter
,visitExit
. This way one could collect thevisits
instead of printing them directly, and whenever anExit
marker is reached, the collectedvisits
can be combined. Fowler - Define an overall default ordering that fits our needs, like the print ordering
I think I like the first idea best -- when I have some time I'll work on this a bit more.