in reply to Re^3: How do I return a hash from Parse::RecDescent?
in thread How do I return a hash from Parse::RecDescent?

You still can't PreCompile that. You're forcing the calling script to parse the parser's grammar, generate the parser code and compile the parser code everytime it runs. That's extremely slow, so that's something you only want to do when the grammar is changed.

To achieve that goal, start by making make_grammar.pl as follows:

use strict; use warnings; use Parse::RecDescent (); my $szGrammar = <<'__END_OF_GRAMMAR__'; { use strict; use warnings; use constant DEBUG => 1; use Data::Dumper; sub AddToHash { print "MyParser->AddToHash(@_)\n" if (DEBUG); my ($this, $szVar, $szValue) = @_; $this->{Result}->{$szVar} = $szValue; } sub GetResult { print "MyParser->GetResult(@_)\n" if (DEBUG); my ($this) = @_; return $this->{Result}; } sub DumpResult { print "MyParser->DumpResult(@_)\n" if (DEBUG); my ($this) = @_; print Dumper($this->{Result}); } } test: expr(s) /^\Z/ expr: name '=' /\d+/ { $thisparser->AddToHash($item{name}, $item[-1]); } name: /\w+/ __END_OF_GRAMMAR__ Parse::RecDescent->PreCompile($szGrammar, 'MyParser') or die("Bad Grammar\n");

You run the above once, then you use it as follows:

use strict; use warnings; use MyParser (); my $hParser = MyParser->new(); my $szCode = "x = 1\ny = 2\nz = 3"; $hParser->test($szCode) or die("Bad code\n"); $hParser->DumpResult();

I still stand by my earlier note: I prefer the solution I posted earlier because it doesn't break if backtracking occurs like this one does.

I'd also like to add that <<'__END_OF_GRAMMAR__' ... __END_OF_GRAMMAR__ has fewer issues than q{ ... }.

Replies are listed 'Best First'.
Re^5: How do I return a hash from Parse::RecDescent?
by Outaspace (Scribe) on Sep 24, 2006 at 13:05 UTC
    You are right, didnt used the PreCompile Option yet and in the grammars I use, the compile time is a minor issue (the time to parse is much more relevant). Also my Parser runs in a large script and I need the option to change the grammar from inside my script, without stopping it. But this maybe would be too slow if I executed my script many times in a row. So I accept that your solution is better for the given task.

    Andre