http://www.perlmonks.org?node_id=845797

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

I've been waw-wawing the small project I'm using to learn about Perl 6 grammars. The following is a pared down version of what seems one of the better approaches: replacing the default array with a hash.

Can the parse tree be constructed so as to eliminate the actions class?

Can this be made simpler? (I'm prone to feel I may miss some syntax.)

grammar H { rule TOP {^ <pairs> $} rule pairs { <pair>[ <pair>]* } rule pair { <key>':'<mash> } token key { \w+ } token mash { \w+ } } class H::Actions { method TOP($/) { my %h; for $/<pairs><pair> -> $p { %h{$p<key>} = $p<mash>; } make %h; } method pairs($/){ make $/ } } my $data = " TOP:most skeleton:door " ~ "password:host belief:trust key:mash "; my $m = H.parse( $data, :actions( H::Actions ) ); die unless $m; for $m.ast.kv -> $k, $v { say $k, " -> ", $v; } my %export_me = $m.ast;
Be well,
rir

Replies are listed 'Best First'.
Re: P6: grammar: create a hash instead of array?
by moritz (Cardinal) on Jun 22, 2010 at 06:15 UTC
    You can reduce the complexity in the TOP reduction method by preparing ASTs in the reduction methods of the previous rules (read that backwards to get the actual order of execution):
    class H::Actions { # construct a hash from a list of pairs method TOP($/) { make %($<pairs>.ast); } # construct a list of Str => Match pairs method pairs($/){ make @($<pair>».ast) } # construct a Str => Match pair method pair($/) { make ~$<key> => $<mash> }; }

    You could also try to stuff all the complexity in method TOP, and use meta operators and parallel dispatch to replace the loop, but I think it will be harder to write, read and debug. Still here's an untested suggestion:

    my @a = @($/<pairs><pair>) make %( @a».<key>».Str Z=> @a».<mash> )

    since the hash indexing with .<key> is just a method call, it can be applied to all items in an array or list with <c>».</code> parallel dispatch (or >>. if you are an ASCII fan).

    Z=> is the Zip meta operator with the => pair constructor. It takes an item from each list, constructs a pair from them, then takes the second item from each list etc.

    Perl 6 - links to (nearly) everything that is Perl 6.