Pointer think is complicating your life. Instead you need to wear a Perl hat and think about references. Consider:
use strict;
use warnings;
use Data::Dumper;
my $data;
my $fsm = 1;
my $module = '';
my $instance = '';
my $entryRef;
while (<DATA>) {
chomp;
if (/^INSTANCE:\s+(\S+)/) {
$module = '';
$instance = $1;
} elsif (/^MODULE:\s+(\S+)/) {
$module = $1;
$instance = '';
} elsif (/^Fsm\s+(\S+)/) {
next if !$fsm;
if ($module) {
$entryRef = $data->{'module'}{$module}{$1} ||= {};
} else {
$entryRef = $data->{'instance'}{$instance}{$1} ||= {};
}
} elsif (/^State\s+(\S+)/) {
next if !$fsm;
push(@{$entryRef->{'state'}}, "$1");
} elsif (/^Transition\s+(\S+)/) {
next if !$fsm;
push(@{$entryRef->{'transition'}}, "$1");
}
}
print Dumper($data);
__DATA__
INSTANCE: i_name
Fsm f_name
State s_name1
Transition t_name
State s_name2
Prints:
$VAR1 = {
'instance' => {
'i_name' => {
'f_name' => {
'transition' =>
+[
+ 't_name'
+],
'state' => [
's_
+name1',
's_
+name2'
]
}
}
}
};
Note in particular that where $entryRef is assigned values ...{$1} ||= {}; is used to assign a hash to the data strcture if there isn't one already.
True laziness is hard work