Why does RecDescent take so long? Is it because your grammar is complex? If that's the case, you could two a bi-level pass using Parse::RecDescent. The idea is that you would define a simple grammar that parses cell ... { ... } and then passes parsed output from the first parser into a call to Parse::RecDescent with your more complex grammar. This is guessing about the reason for RecDescent being slow on your data.
Another option is to write your own simple parser that matches on the cell entries, counts the number of braces it's seen so far, and then finds the matching brace when the closing brace count is equal to the opening brace count. That should be fast, but the suggestion above might be faster to implement and easier to maintain.
Edit: You should definitely try Parse::RecDescent with a simplified grammar. The algorithmic complexity of recursive descent parsing is proportional to the number of possible parse trees, which should be something like is B ^ N, where B is the number of branching points in your grammar, and N is the number of nodes.
If you'd like to try rolling your own simple parser for a first pass over your input, the following code can get you started.
#!/usr/bin/perl -w
use strict;
my $input_file = "input";
open FILE, "<$input_file" or die $!;
my $in_block = 0;
my $current_block = '';
my $open_bracket_count = 0;
while( my $line = <FILE> ) {
if ( $line =~ /cell/ ) {
$in_block = 1;
}
if ( $in_block ) {
while ( $line =~ /([\{\}]{1})/g ) {
my $token = $1;
if ( $token eq '{' ) {
$open_bracket_count++;
} elsif ( $token eq '}' ) {
$open_bracket_count--;
}
}
$current_block .= $line;
}
if ( $open_bracket_count == 0 && $current_block ne '' ) {
print '-' x 80, "\n";
print $current_block, "\n";
$in_block = 0;
$current_block = '';
}
}
close FILE or die $!;
Edit: changed code to avoid slurping the entire file into memory. While this is trivial for an 8MB file, it's cleaner to just read the file in line-by-line.