Subject: | failed subrules eat text |
perl version 5.10.1 built for i686-cygwin-thread-multi-64int
Parse::RecDescent version 1.965001
I would expect attached test to print "NO MATCH", but in fact, it matches.
The problem seems to be this line in generated code:
unless ( $_matched || defined($score) )
{
...
$_[1] = $text; # NOT SURE THIS IS NEEDED <====
...
}
$text is modified by the successful match of 'one'. Assigning back to
the argument propagates this modification up the chain.
Applying the attached patch fixes this bug, but I don't know what it
might break. I can't think of a reason that you would ever want to
propagate a $text change upwards on failure, but I may not have a good
enough imagination.
Subject: | failed_subrules_eat_text.pl |
#!/usr/bin/perl -w
use strict;
use warnings;
use Parse::RecDescent;
my $text = "one ;";
my $parser = Parse::RecDescent->new(<<'EOGRAMMAR');
TOP:
<leftop: element /,/ element>(s?) ';'
element:
'one' 'two'
EOGRAMMAR
local $::RD_TRACE = 1;
if (defined $parser->TOP($text)) {
print "===== MATCHED ====\n";
} else {
print "===== NO MATCH ===\n";
}
Subject: | failed_subrules_eat_text.patch |
*** RecDescent.pm.orig 2010-11-10 07:02:39.607127500 -0500
--- RecDescent.pm 2010-11-10 07:02:06.013162500 -0500
*************** sub ' . $namespace . '::' . $self->{"nam
*** 441,447 ****
'
: '') . '
! $_[1] = $text; # NOT SURE THIS IS NEEDED
Parse::RecDescent::_trace(q{<<Didn\'t match rule>>},
Parse::RecDescent::_tracefirst($_[1]),
q{' . $self->{"name"} .'},
--- 441,447 ----
'
: '') . '
! #$_[1] = $text; # NOT SURE THIS IS NEEDED
Parse::RecDescent::_trace(q{<<Didn\'t match rule>>},
Parse::RecDescent::_tracefirst($_[1]),
q{' . $self->{"name"} .'},