Sigil has asked for the wisdom of the Perl Monks concerning the following question:

Hi. I need to get the return data from a Parse::RecDescent parse tree created with the autotree directive.

Below is an example based on the article Parse::RecDescent Tutorial

The visitor function below seems to work. $AUTOLOAD instead of the switch statement would also be interesting.

But I'm wondering, is it really that simple? Or have I overlooked something?

Thanks.

use strict; use warnings; use Parse::RecDescent; use Switch; use Scalar::Util 'blessed'; my $grammar = q( <autotree> startrule : day month date day : "Sat" | "Sun" | "Mon" | "Tue" | "Wed" | "Thu" | "Fri" month : "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" date: /\d+/ ); my $parser = Parse::RecDescent->new($grammar); my $tree = $parser->startrule("Thu Mar 31"); visit($tree); sub visit { my ($v) = @_; if ( blessed($v) ) { switch ( ref($v) ) { case "date" { print "The date is: ", $v->{__VALUE__}, "\n"; } case "month" { print "The month is: ", $v->{__VALUE__}, "\n"; } } foreach my $key ( keys %$v ) { visit( $v->{$key} ); } } }

Replies are listed 'Best First'.
Re: Parse::RecDescent autotree visitor
by jethro (Monsignor) on Aug 10, 2011 at 09:49 UTC

    No it isn't that simple. We have "Wed Aug 10" already ;-)

    What do you expect from us? Should we do the testing for you? If you want to make sure, you could change your script to a module and write a test script that feeds different expressions and compares the output with what it should produce. See Test::Simple and Test::More or read Ian Langworths and Chromatics excellent book "perl testing"

    As a quick test you could also use Data::Dumper to show you what data structure your script produces

      Ok. Thanks. My question was to vague. I'm hoping for design assistance versus help with debugging. I did use Data::Dumper.

      More specifically: It seems the classic visitor pattern (accept, visit methods) is unnecessary in Perl because of Perl's simple support for reflection and autoloading. Is that correct? (It seems like that was the intention with PRD autotree?)

      Also, do I need to track visited nodes? Is there a way that the visit sub could create an infinite loop while walking a parse tree?

      Thanks.

        The built-in OO system in perl is really a basic set to object-orientation. It works quite well and if you want more distance to the nitty-gritty it allows you to build modules to get inside-out objects or have a more refined OO with Moose for example. So it isn't uncommon that OO features of the system are used for any purpose that fits.

        Naturally I can't look in the mind of Damian Conway, but I would guess that he just used the bless to store an attribute (the name of the token) so that the hash doesn't need a special key for it. While I'm sure he knows patterns I would guess that designing for or avoiding this pattern was not his intention. It was just a good use for objects and bless.

        And no to your second question, a loop in the parse tree would be a bug.