Skip Menu |

This queue is for tickets about the Parse-RecDescent CPAN distribution.

Report information
The Basics
Id: 736
Status: resolved
Priority: 0/
Queue: Parse-RecDescent

People
Owner: Nobody in particular
Requestors: yves.canty [...] ericsson.ca
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: RecDescent incorrectly parses code in actions
Hi, The following problem has been reproduced under the following conditions: RecDescent 1.80 SunOS steamtown 5.8 Generic_108528-10 sun4u sparc SUNW,Sun-Blade-100 perl, version 5.005_03 built for sun4-solaris perl, v5.6.1 built for sun4-solaris-thread-multi (Binary build 626 provided by ActiveState) I found what seems to be a bug in the way RecDescent 1.80 extracts code fragments from actions, in very specific circumstances. I'm using a grammar within an object-oriented module I wrote. In order for the grammar to interact with an instance of my object, I pass the object instance as an argument to the start rule and store that as a local rulevar. I then use that object within the grammar. That seems to work fine in general. However, I found a very weird instance where this does not work: I wanted to capture all errors generated by RecDescent into my object instance, so I used code similar to what is described in the FAQ. Included below is a complete script that shows what I mean. If you run that script with RecDescent 1.80, you should get the following errors: Warning: Undefined (sub)rule "word" used in a production. Warning: Undefined (sub)rule "EOFILE" used in a production. Run it with $::RD_TRACE enabled, and look for the error-catching action code in the RD_TRACE file: it's not there (do a 'grep _add_errors RD_TRACE' for example). This seems to be caused by the following line: $obj->_add_errors("Error at line $line: $msg\n"); Either comment out the above line from the grammar, or just try adding the following line of code right after that line: print(""); If you do that, the grammar errors will magically go away. Looking at RD_TRACE again, you will find that the error-catching code has been correctly included (for example 'grep _add_errors RD_TRACE' will find one matching line). In the real, more complex grammar I wrote, RD_TRACE shows that under the above conditions, RecDescent mistakenly goes past the action block that contains the $obj->_add_errors() call, and identifies a big chunk of the grammar as being part of that action, thus resulting in an invalid grammar (or so it thinks!). -- Cut here -- use strict; use Parse::RecDescent; my $grammar = <<'EOF'; grammar : <rulevar: local $obj = $arg[0]> grammar : word(s?) EOFILE { return $item[1]; } | # The following action will generate grammar errors # unless you comment out the $obj line, or # add any valid perl code after it. { foreach my $err (@{$thisparser->{errors}}) { my $line = $err->[1]; my $msg = $err->[0]; $obj->_add_errors("Error at line $line: $msg\n"); } $thisparser->{errors} = undef; } word : m/\w+/ EOFILE : /^\Z/ EOF my $obj = Object->new(); my $grammar = Parse::RecDescent->new($grammar); $grammar->grammar("This is a test", 1, $obj); $obj->print_errors(); package Object; sub new { my($class) = @_; return bless ( { _error => [ ] }, ref($class) || $class); } sub _add_errors { my($self, @err) = @_; push(@{$self->{_error}}, @err); } sub print_errors { my($self) = @_; print(join("", @{$self->{_error}}), "\n"); } Show quoted text
--- Cut here ---
This appears to be an old issue against an old version of Parse::RecDescent. I was unable to reproduce the error with the supplied example. If you are able to produce this error with the latest release of Parse::RecDescent, please let me know and I'll look into it. Also, please attach your test script as a file to preserve the whitespace/formatting, which may be a part of the issue. Thank you for taking the time to file a bug.