Subject: | $thisline is easily confused - even with resync |
Running the attached test script "linetest.pl", the output is ...
$ ./linetest.pl
Show quoted text
>>> a 1
>>> a 2
>>> b 3
>>> c 9
>>> a 6
>>> a 7
>>> c 8
>>> b 9
>>> c 15
>>> a 7
>>> a 8
>>> c 14
>>> c 15
Applying the attached patch, the output is:
$ ./linetest.pl
Show quoted text>>> a 1
>>> a 2
>>> b 3
>>> c 3
>>> a 5
>>> a 6
>>> c 7
>>> b 9
>>> c 9
>>> a 11
>>> a 12
>>> c 13
>>> c 15
which, if nothing else, is at least monotonically non-decreasing.
I'm not sure the %counter_cache really buys anything. And given that it
is a package lexical, every running parser will share it. So, if I start
a "sub-parser" inside an action, the cache will contain a strange mix of
data.
Subject: | linetest.pl |
#!/usr/bin/perl -w
use strict;
use warnings;
use lib './blib/lib';
use Parse::RecDescent;
#$::RD_TRACE = 1;
my $p = Parse::RecDescent->new(<<'GRAMMAR');
TOP: token(s) /\z/
token:
'a' { print ">>> a $thisline\n" }
| 'b' { print ">>> b $thisline\n"; $text = "c\n\na\na\nc\n" . $text;
Parse::RecDescent::LineCounter::resync($thisline) }
| 'c' { print ">>> c $thisline\n"; }
GRAMMAR
defined($p) or die "FAILED to create parser\n";
defined($p->TOP("a\na\nb\nb\nc\n")) or die "FAILED to parse.";
Subject: | linecounter.patch |
*** RecDescent.pm.orig 2010-11-18 11:36:02.722933000 -0500
--- RecDescent.pm 2010-11-18 11:37:28.723483400 -0500
*************** sub FETCH
*** 113,119 ****
unless (exists $counter_cache{$from}) {
$parser->{lastlinenum} = $parser->{offsetlinenum}
! - Parse::RecDescent::_linecount(substr($parser->{fulltext},$from))
+ 1;
$counter_cache{$from} = $parser->{lastlinenum};
}
--- 113,119 ----
unless (exists $counter_cache{$from}) {
$parser->{lastlinenum} = $parser->{offsetlinenum}
! - Parse::RecDescent::_linecount(${$_[0]->{text}})
+ 1;
$counter_cache{$from} = $parser->{lastlinenum};
}
*************** sub resync # ($linecounter)
*** 139,144 ****
--- 139,145 ----
+ 1;
$parser->{offsetlinenum} += $parser->{lastlinenum} - $apparently;
+ %counter_cache = ();
return 1;
}
*************** A subrule which appears in a production
*** 3372,3378 ****
attempt to match the named rule at that point in the text being
parsed. If the named subrule is not defined when requested the
production containing it immediately fails (unless it was "autostubbed" - see
! L<Autostubbing>).
A rule may (recursively) call itself as a subrule, but I<not> as the
left-most item in any of its productions (since such recursions are usually
--- 3373,3379 ----
attempt to match the named rule at that point in the text being
parsed. If the named subrule is not defined when requested the
production containing it immediately fails (unless it was "autostubbed" - see
! L<"Autostubbing">).
A rule may (recursively) call itself as a subrule, but I<not> as the
left-most item in any of its productions (since such recursions are usually