use strict; use warnings; use Parse::RecDescent; use Data::Dumper; our $RD_TRACE=1; my $Grammar=<<'END_GRAMMAR'; {my $company=""} startrule : file file : header record(s?) trailer_t { $return={header=>$item[1],records=>$item[2],count=>$item[3]}; 1; } header : header_t data_t { $return={company=>$item[1],code=>$item[2]}; $text.=shift @::text; print "Company Set to $company\n Text=$text"; 1; } record : valid_record | valid_record: type_t ',' number_t ',' number_t(?) ',' "$company" { $return=[ $item[1],$item[3],@{$item[5]} ? $item[5] : undef ]; $text.=shift @::text; print "Text=$text"; 1; } header_t : /HDR\w+/ {$return=substr($item[1],3); $company=$return;1;} trailer_t : /TLR\d+/ {$return=substr($item[1],3)} data_t : /\w+/ type_t : /ADD(?:RANGE)?|DELETE(?:RANGE)?/ number_t : /\d+/ END_GRAMMAR my $parser = Parse::RecDescent->new($Grammar) or die "Bad grammar!\n"; our @text=; if (defined( my $t=$parser->startrule(shift @text))) { print Dumper($t); } else { print "Bad text!\n"; } __DATA__ HDRCOMPNAME BIG000OLD111IDENTIFIER1020301WITH1010LOTS1010OF1010CRAP ADD,1234567890,,COMPNAME ADD,1234567891,,COMPNAME ADD,1234567892,,COMPNAME ADDRANGE,1468,1680,COMPNAME ADDRANGE,2468,2680,COMPNAME ADDRANGE,3468,3680,COMPNAME DELETE,987654321,,COMPNAME DELETE,987654322,,COMPNAME DELETE,987654323,,COMPNAME DELETERANGE,13579,13599,COMPNAME DELETERANGE,23579,23599,COMPNAME DELETERANGE,33579,33599,COMPNAME TLR000012