我有一个输入源,如下所示。我想做的是将每个Layer
行上的数值捕获到一个数组中,然后打印出最大值。
输入
MACRO cell_1
size 0.1 by 0.1 ;
pin a
(....same topology as pin vcc)
END a
pin b
(.....same topology as pin vcc)
END b
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc
pin d
(....same topology as pin vcc)
END d
END cell_1
MACRO cell_2
(repeated)
END cell_2
我的代码:
foreach my $file ( @files ) { # @files = multiple path of abc/def/fgh/cell_lef
open( INFILE, "<$file" ) || die "Can not open stdcell_filen";
my @lines = <INFILE>;
close INFILE;
$init = 1;
$delimiter =~ /^$/; # between each MACRO. haven't utilize this yet
foreach (@lines) {
if ( $init ) {
$path = 1;
$init = 0;
@num = ();
}
if ( $path ) {
if ( /MACROs+(S+) /) {
$cellname = $1; print "$cellnamen";
}
if ( /SIZEs+(S+)s+(S+)s+(S+)/ ) {
$footprint_x = $1;
$footprint_y = $3;
print "$footprint_x $footprint_yn";
}
if ( /PIN vcc/ .. /END vcc/ ) {
#grab the highest value from layer (m*)
#print "max layer = m*"
}
$init = 1;
}
}
}
预期输出
cell_1
0.1 0.1
m2
cell_2
0.2 0.2
m3
我尝试使用的代码:
if ( /PIN vcc/../END vcc/ ) {
if ( /LAYERs+m(S+) / ) {
push(@num, $1);
print "@num";
}
}
到目前为止,我的代码的问题是,当我打印@num
的值时,所有的值都作为字符串(210
)连接在一起,而不是单个元素:2 1 0
——所以我无法进行排序以获得最大值。
更新:我不确定如何将while
集成到我的代码中,因为我使用foreach作为我的主循环
您的代码正在捕获数字,好吧,只是您正在打印整个数组。当您打印数组时,Perl默认的数组元素分隔符是""
,也就是说,什么都没有——所以,它看起来像一个字符串,但它是三个(或多个)相邻打印的元素,没有分隔符。
您可以使用while (<>) {
以Unix过滤器样式逐行迭代输入。您可以在找到"PIN vcc"时打开"扫描模式"标志,在找到"END vcc"后将其关闭。之后,使用正则表达式搜索图层行,但始终使用"扩展模式"/x
,这样您就可以在正则表达式中使用空白。
由于用于切换模式和捕获层数的正则表达式是互斥的,您可以让其他检查在检查成功后进行-只需注意,如果未来的更改导致重叠情况,则需要在其中一个正则表达式成功时执行next
。
最后,List::Util是一个核心模块,因此,您不妨从中获取max函数;
use v5.12;
use warnings;
use List::Util qw( max );
my @num ;
my $scanning = 0;
while (<>) {
$scanning = 1 if /PIN vcc/ ;
$scanning = 0 if /END vcc/ ;
next unless $scanning ;
push @num, $1 if /Layer s+ m (d+) /x ;
}
say "Max layer number found: ", max(@num) ;
或者只需使用的sort
函数即可。
my @values ;
while (<DATA>)
{
push (@values , $1) if (/Layers+m(d+)s;/);
}
my ($max) = sort{$b <=> $a} @values ;
print "$maxn";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
使用CCD_ 11函数并将第一个结果存储到包含变量CCD_。
my @data = <DATA> ;
my @num ;
foreach (@data) {
push @num, $1 if /Layers+m(S+)/ ;
}
# home made max() - sorts an anonymous array and prints the last element
print [ sort { $a <=> $b } @num ]->[-1] , "n" ;
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m2 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
END vcc
使用map
从文件中提取数字。sort
的数量,得到最大数量。
#!/usr/bin/perl
use strict;
use warnings;
my $max = (sort{$b <=> $a }map{/Layers+m(d+)/} <DATA>)[0];
print $max,"n";
__DATA__
Pin vcc
aaaa
bbbb
Port
Layer m3 ;
END
CCC
DDD
Port
Layer m1 ;
END
EEE
FFF
Port
Layer m0 ;
END
首先,如果只查找最大值,则不需要存储所有值;第二,循环结束后打印最大值,
my $max = "-inf";
if (/PIN vcc/ .. /END vcc/) {
$max = $1 if /LAYERs+m(S+)/ and $max < $1;
}
# ..
print $max, "n";