Hello ameezys. You do not give much information on how you want the gate information stored. It depends on what you want to do with it.
I only see nand in your example, but there are not's and's etc.
If you want to easily loop over only nand or only not then I suggest:
$GATE{$gate_type}{$gate_name} = { ... hash object with fields ... }
And then build arrays of these objects to loop over them. (the %LINK variable). As pointers/references, so hopefully RAM efficient.
But you can also store hash objects in an array (but I did not do that in the code) which makes it less cluttered, but harder to loop through.
First I modified the regexp a bit so that it is tolerant to a space here and there. But a separate regexp needs to be made to handle the not as it has less parameters
To have the array you want, just loop over the keys:
# Obtain the @input_A array from %LINK
my @input_A_from_link = keys %{$LINK{'input_A'}};
die Dumper(\@input_A_from_link);
or, if you do not want the helper hash, directly from the data (using a oneliner):
# get all input_A for nand, not, and, etc..
my @all_input_A = map { my $g = $_; @_=keys $GATE{$g}; map {$GATE{$g}{
+$_}->{'A'}} @_ } keys %GATE;
die Dumper(\@all_input_A);
The code (sorry, a bit messy):
#!/usr/bin/perl
use warnings;
use Data::Dumper;
use [METAMOD://List::MoreUtils] qw/ uniq /;
my %GATE;
my %LINK;
while(<DATA>){
chomp;
my $gate_DATA = $_;
if (defined($gate_DATA) && ($gate_DATA =~ /(.*)\s+(.*)\s+\(\s*(.*)\s
+*,\s*(.*)\s*,\s*(.*)\s*\);/) && ($gate_DATA !~ /module/) ){
# $gate_type = $1;
# $gate_name = $2;
$output_gate = $3;
$input_A = $4;
$input_B = $5;
die "Line $.: FATAL Redefinition of gate $gate_DATA\n" if(defined
+$GATE{$gate_type}{$gate_name});
$GATE{$gate_type}{$gate_name} = {
'name' => $gate_name,
'type' => $gate_type,
'out' => $output_gate,
'A' => $input_A,
'B' => $input_B,
};
push @{$LINK{'input_A'}{$input_A}}, $GATE{$gate_type}{$gate_name};
push @{$LINK{'input_B'}{$input_B}}, $GATE{$gate_type}{$gate_name};
push @{$LINK{'output'}{$output_gate}}, $GATE{$gate_type}{$gate_nam
+e};
}
}
# uncomment to Show the structure of %GATE
# die Dumper(\%GATE);
# uncomment to Show the structure of %LINK
# die Dumper(\%LINK);
# Yeah, %LINK is a hash of a hash of an array of a referenced hash
# die Dumper($LINK{'input_A'}{'N11'}[0]->{'A'});
# die Dumper($LINK{'output'}{'N19'}[0]->{'A'});
# loop over input_A and show where it outputs to
for my $gate (keys %{$LINK{'input_A'}}){
my @outputs = map { $_->{'out'} } grep { defined $_->{'out'} } @{$LI
+NK{'input_A'}{$gate}};
print "input gate $gate has output @outputs\n";
}
# This is how you access the data of one gate:
# print $GATE{'nor'}{'NOR2_1'}->{'out'};
# get nand input_A, note the use of uniq to have a unique list (still
+not sorted, though)
my @nand_input_A = uniq map { $GATE{'nand'}{$_}->{'A'} } keys %{$GATE{
+'nand'}};
# get all input_A for nand, not, and, etc..
my @all_input_A = map { my $g = $_; @_=keys $GATE{$_}; map {$GATE{$g}{
+$_}->{'A'}} @_ } keys %GATE;
# get all input_A for nand, not, and, etc... but this time, use readab
+le perl
my @all_input_A_normal;
for my $gate_type (keys %GATE){
for my $gate_name (keys %{$GATE{$gate_type}}){
if(defined $GATE{$gate_type}{$gate_name}->{'A'}){
push @all_input_A_normal, $GATE{$gate_type}{$gate_name}->{'A'};
}
}
}
print Dumper(\@all_input_A_normal);
__DATA__
nand nand2_1 (N10,N1,N3);
nand nand2_2 (N11,N3,N6);
nand nand2_3 (N16,N11,N2);
nand nand2_4 (N19,N11,N7);
nand nand2_5 (N22,N10,N16);
nand nand2_6 (N23,N16,N19);
nor NOR2_1 (N6875, N6722, N6476);