The included patch, a result of a bit of time with Devel::Profiler, speeds
up RecDescent by almost a factor of two on a grammar of mine by doing two
things:

(1) Caching Rule::expected() results;

(2) Inlining Expectation::is() and Expectation::at().

There's also a third change, removing a "my " where it gave me a syntax
error in precompiled grammars.  I've got the latest Data::Dumper
installed, so I'm not sure why this would be a problem only for me.

Please let me know if this seems like a good idea, or if some of you see
other similar improvements.

/s
--- lib/Parse/RecDescent.pm     Fri Jan 19 10:02:51 2001
+++ /usr/local/lib/perl5/site_perl/5.6.1/Parse/RecDescent.pm    Thu Jul  4 12:10:13 
+2002
@@ -78,7 +78,8 @@ sub Precompile
                print OUT $self->_code();
 
                print OUT "}\npackage $class; sub new { ";
-               print OUT "my ";
+# SEAN: this is bad.
+#              print OUT "my ";
 
                require Data::Dumper;
                print OUT Data::Dumper->Dump([$self], [qw(self)]);
@@ -260,6 +261,7 @@ sub leftmostsubrules($)
 sub expected($)
 {
        my $self = shift;
+       return $self->{"expected"} if exists($self->{"expected"});
        my @expected = ();
 
        my $prod;
@@ -272,7 +274,7 @@ sub expected($)
                }
        }
 
-       return join ', or ', @expected;
+       return $self->{"expected"} = join ', or ', @expected;
 }
 
 sub _contains($@)
@@ -297,6 +299,7 @@ sub addprod($$)
        my ( $self, $prod ) = @_;
        push @{$self->{"prods"}}, $prod;
        $self->{"changed"} = 1;
+       delete $self->{"expected"};
        $self->{"impcount"} = 0;
        $self->{"opcount"} = 0;
        $prod->{"number"} = $#{$self->{"prods"}};
@@ -382,7 +385,7 @@ sub ' . $namespace . '::' . $self->{"nam
        my $text;
        my $lastsep="";
        my $expectation = new Parse::RecDescent::Expectation($thisrule->expected());
-       $expectation->at($_[1]);
+       $expectation->{lastunexpected} = $_[1];
        '. ($parser->{_check}{thisoffset}?'
        my $thisoffset;
        tie $thisoffset, q{Parse::RecDescent::OffsetCounter}, \$text, $thisparser;
@@ -1099,8 +1102,9 @@ my $code = '
                                          q{' . $rule->{name} . '})
                                                if defined $::RD_TRACE;
                $lastsep = "";
-               $expectation->is(q{' . ($rule->hasleftmost($self) ? ''
-                               : $self->describe ) . '})->at($text);
+               $expectation->{lastexpected} = q{' . ($rule->hasleftmost($self) ? ''
+                               : $self->describe ) . '};
+               $expectation->{lastunexpected} = $text;
                ' . ($self->{"lookahead"} ? '$_savetext = $text;' : '' ) . '
 
                ' . ($self->{"lookahead"}<0?'if':'unless')
@@ -1170,8 +1174,9 @@ my $code = '
                                          q{' . $rule->{name} . '})
                                                if defined $::RD_TRACE;
                $lastsep = "";
-               $expectation->is(q{' . ($rule->hasleftmost($self) ? ''
-                               : $self->describe ) . '})->at($text);
+               $expectation->{lastexpected} = q{' . ($rule->hasleftmost($self) ? ''
+                               : $self->describe ) . '};
+               $expectation->{lastunexpected} = $text;
                ' . ($self->{"lookahead"} ? '$_savetext = $text;' : '' ) . '
 
                ' . ($self->{"lookahead"}<0?'if':'unless')
@@ -1239,8 +1244,9 @@ my $code = '
                                          q{' . $rule->{name} . '})
                                                if defined $::RD_TRACE;
                $lastsep = "";
-               $expectation->is(q{' . ($rule->hasleftmost($self) ? ''
-                               : $self->describe ) . '})->at($text);
+               $expectation->{lastexpected} = q{' . ($rule->hasleftmost($self) ? ''
+                               : $self->describe ) . '};
+               $expectation->{lastunexpected} = $text;
                ' . ($self->{"lookahead"} ? '$_savetext = $text;' : '' ) . '
 
                ' . ($self->{"lookahead"}<0?'if':'unless')
@@ -1321,9 +1327,10 @@ sub code($$$$)
                                  q{' . $rule->{"name"} . '})
                                        if defined $::RD_TRACE;
                if (1) { no strict qw{refs};
-               $expectation->is(' . ($rule->hasleftmost($self) ? 'q{}'
-                               # WAS : 'qq{'.$self->describe.'}' ) . ')->at($text);
-                               : 'q{'.$self->describe.'}' ) . ')->at($text);
+               $expectation->{lastexpected} = ' . ($rule->hasleftmost($self) ? 'q{}'
+                               # WAS : 'qq{'.$self->describe.'}' ) . ')->($text);
+                               : 'q{'.$self->describe.'}' ) . ';
+               $expectation->{lastunexpected} = $text;
                ' . ($self->{"lookahead"} ? '$_savetext = $text;' : '' )
                . ($self->{"lookahead"}<0?'if':'unless')
                . ' (defined ($_tok = '
@@ -1434,9 +1441,9 @@ sub code($$$$)
                                  Parse::RecDescent::_tracefirst($text),
                                  q{' . $rule->{"name"} . '})
                                        if defined $::RD_TRACE;
-               $expectation->is(' . ($rule->hasleftmost($self) ? 'q{}'
-                               # WAS : 'qq{'.$self->describe.'}' ) . ')->at($text);
-                               : 'q{'.$self->describe.'}' ) . ')->at($text);
+               $expectation->{lastexpected} = ' . ($rule->hasleftmost($self) ? 'q{}'
+                               : 'q{'.$self->describe.'}' ) . ';
+               $expectation->{lastunexpected} = $text;
                ' . ($self->{"lookahead"} ? '$_savetext = $text;' : '' ) .'
                unless (defined ($_tok = $thisparser->_parserepeat($text, '
                . $self->callsyntax($namespace.'::')
@@ -1529,9 +1536,9 @@ sub code($$$$)
                                  Parse::RecDescent::_tracefirst($text),
                                  q{' . $rule->{"name"} . '})
                                        if defined $::RD_TRACE;
-               $expectation->is(' . ($rule->hasleftmost($self) ? 'q{}'
-                               # WAS : 'qq{'.$self->describe.'}' ) . ')->at($text);
-                               : 'q{'.$self->describe.'}' ) . ')->at($text);
+               $expectation->{lastexpected} = ' . ($rule->hasleftmost($self) ? 'q{}'
+                               : 'q{'.$self->describe.'}' ) . ';
+               $expectation->{lastunexpected} = $text;
 
                $_tok = undef;
                OPLOOP: while (1)
@@ -1642,16 +1649,6 @@ sub new ($)
              };
 }
 
-sub is ($$)
-{
-       $_[0]->{lastexpected} = $_[1]; return $_[0];
-}
-
-sub at ($$)
-{
-       $_[0]->{lastunexpected} = $_[1]; return $_[0];
-}
-
 sub failed ($)
 {
        return unless $_[0]->{lastexpected};
@@ -2767,7 +2764,8 @@ sub _parserepeat($$$$$$$$$$)      # RETURNS A
        my $reps;
        for ($reps=0; $reps<$max;)
        {
-               $_[6]->at($text);        # $_[6] IS $expectation FROM CALLER
+               # $_[6] IS $expectation FROM CALLER
+               $_[6]->{lastunexpected} = ($text);
                my $_savetext = $text;
                my $prevtextlen = length $text;
                my $_tok;

Reply via email to