Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re^3: How to grab Parse::RecDescent error output in a variable?

by tfrayner (Curate)
on Sep 15, 2008 at 13:09 UTC ( #711452=note: print w/replies, xml ) Need Help??

in reply to Re^2: How to grab Parse::RecDescent error output in a variable?
in thread How to grab Parse::RecDescent error output in a variable?

Curious; as it happens I had to do this for a project I was working on some months back, and came to the same conclusion as ikegami. My code reads thusly (copied and pasted):
open( *Parse::RecDescent::ERROR, '>', \(my $parse_error) ) or croak("Error: unable to redirect SDTERR."); $Parse::RecDescent::skip = ' *\x{0} *'; $::RD_ERRORS++; $::RD_WARN++; $::RD_HINT++; my $parser = Parse::RecDescent->new($grammar) or die("Bad grammar! +");
I can assure you that does actually work for me (perl 5.8.8, P::RD 1.94). My best guess is that your use of local on that open call is maybe creating problems?

The dependency on P::RD internals always bothered me as well, but I never got around to figuring out a better way to do this.

Cheers, Tim

Update: Yup, turns out if you remove that local then it works:
use strict; use Parse::RecDescent; sub parse { my ($grammar, $str) = @_; open(*Parse::RecDescent::ERROR, '>', \my $error) or die "Cannot open in-memory filehandle: $!"; local $::RD_ERROR = 1; local $::RD_WARN = 2; my $p = Parse::RecDescent->new($grammar) or die "Grammar is invalid"; my $x = $p->start($str); defined $x or die "CAPTURED: $error"; return $x; } print parse('start: /foo/ | <error>', 'fo'), "\n";

Replies are listed 'Best First'.
Re^4: How to grab Parse::RecDescent error output in a variable?
by Pic (Scribe) on Sep 15, 2008 at 17:12 UTC

    The reason local breaks it is that local replaces the variable in that lexical scope, and the references to P::RD::ERROR in P/ are outside the lexical scope of the local invocation (I think).

    It's an interesting question though, and IMO the right solution would be to get a patch committed for P::RD that allows the user to specify an alternative filehandle for error output.

      Done, and also received feedback already! Here's the bug report:

      And here's the solution I was seeking, based on demo/

      use strict; use Data::Dumper; use Parse::RecDescent; # Simple Lisp S-expressions (as an example) my $grammar = q# start: expression(s?) | { die join("\n", map { $_->[0] } @{ $thisparser->{errors} } +)."\n" } expression: /\w+/ | '(' expression(s?) ')' { $item[2] } | <error> #; my $p = Parse::RecDescent->new($grammar); # This will die if there is an error. print Dumper($p->start('(foo (bar))')); # Like so: $p->start('(foo');

      say "Just Another Perl Hacker";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://711452]
[erix]: record separator
[Cosmic37]: Permissions are interesting earthlings. Did nature determine who gives permission and who asks permission. Who was the first to get permission? Are you not related to them as one big earthling family?
[karlgoethebier]: Cojones! We need cojones!
[karlgoethebier]: Ouch! Permissions! We need permissions!
[BarApp]: I can not use modules. I gain temporary access and still can not use modules.
[Cosmic37]: ta erix - this szabo geezer is pretty cool methinks and he writes about undef but I cannot see instructions for redefining the record separator after having undefined it
[Corion]: $/ = "wahtever";

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2017-06-29 16:39 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (672 votes). Check out past polls.