parallel class structures for AST-based objects

Steve Howell showell30 at yahoo.com
Sun Nov 22 12:27:08 EST 2009


On Nov 22, 7:55 am, Simon Forman <sajmik... at gmail.com> wrote:
> On Sun, Nov 22, 2009 at 4:50 AM, Diez B. Roggisch <de... at nospam.web.de> wrote:
>
>
>
> > Steve Howell schrieb:
>
> >> On Nov 21, 4:07 pm, MRAB <pyt... at mrabarnett.plus.com> wrote:
>
> >>> I don't see the point of EvalNode and PrettyPrintNode. Why don't you
> >>> just give Integer, Sum and Product 'eval' and 'pprint' methods?
>
> >> That's a good question, and it's the crux of my design dilemma.  If
> >> ALL I ever wanted to to with Integer/Sum/Product was to eval() and
> >> pprint(), then I would just add those methods to Integer, Sum, and
> >> Product, and be done with it, as you suggest.  But what happens when
> >> somebody wants to extend capability?  Should every future software
> >> developer that wants to use Integer/Sum/Product extend those classes
> >> to get work done?  What if they want to store additional state for
> >> nodes?
>
> > What's usually done is to create visitors/matchers. Those traverse the AST,
> > and either only visit, or return transformed versions of it (think e.g.
> > algebraic optimization)
>
> > A visitor will roughly look like this:
>
> > class ASTVisitor(object):
>
> >   def visit(self, node):
> >       name = node.__class__.__name__.lower()
> >       if hasattr(self, "visit_%s" % name):
> >           getattr(self, "visit_%s" % name)(node)
> >       for child in node:
> >           self.visit(child)
>
> > You can of course chose another type of dispatch, using e.g. a generic
> > method.
>
> > Then you create Visitors for specific tasks - pretty-printing, evaluation,
> > rewriting. Those don't have the overhead of your current design with all
> > those factory-mapping stuff, and yet you aren't forced to put logic into AST
> > you don't want there.
>
> FWIW I often use John Aycock's SPARK (Scanning, Parsing, and Rewriting
> Kit) for this sort of thing.  It has a GenericASTTraversal which "is a
> Visitor pattern according to Design Patterns."
>
> http://pages.cpsc.ucalgary.ca/~aycock/spark/
>
> It's apparently distributed with the python source, but it's not in
> the standard library, more's the pity IMO.
>
> There's a bit of a learning curve but it's well worth it.
>

Thanks, Simon, I think something like GenericASTTraversal should work
for me in most cases.

A couple of folks have suggested an idea that is in his paper, which
is to use a single class for something PrettyPrinter, and then use
reflection to find methods on PrettyPrinter to pretty-print sums,
products, integers, etc.





More information about the Python-list mailing list