Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

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]
[ambrus]: Corion: no, backwards. It's possible in the general case, but not in the specific case of bad data we have. Which is why it's harder to explain.
[marto]: that reminds me, to donate...
[ambrus]: If it was possible in this specific case, then the burden to argue for that would be his.
[Corion]: ambrus: Ah, but he's the boss, so the burden to show that it's impossible still lies on you :-)
[Corion]: ambrus: I would work with him through an example

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2017-12-12 13:16 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (332 votes). Check out past polls.