Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

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";


Comment on Re^3: How to grab Parse::RecDescent error output in a variable?
Select or Download Code
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/RD.pm 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: https://rt.cpan.org/Ticket/Display.html?id=39323

      And here's the solution I was seeking, based on demo/demo_errors.pl:

      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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://711452]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (12)
As of 2015-07-30 21:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (273 votes), past polls