Re: Complicated Search and Replace
by ikegami (Patriarch) on Jun 27, 2005 at 18:24 UTC
|
What follows is a recursive solution. The expressions are paired, then the pairs are paired, then the paired pairs are paired, etc. until only one expression is left.
use strict;
use warnings;
my $command = '@MAC(output,X,Y,8);';
my ($fields) = $command =~ /\@MAC\((.*?)\)/;
my ($output, $var1, $var2, $size) =
split(/\s*,\s*/, $fields);
my @data = map { "$var1$_*$var2$_"} (0 .. $size-1);
while (@data > 1) {
my @compressed;
push @compressed, sprintf("(%s)+(%s)", shift(@data), shift(@data))
while @data;
@data = @compressed;
}
print("$output = $data[0];\n");
| [reply] [d/l] |
|
|
Wow. That was quick. I was trawling through the man pages trying to come up with something to post so I didn't look like such a freeloader... Your solution works. Try putting in 8192 and you'll appreciate how much time is to be saved!
Thanks
| [reply] |
|
|
Try putting in 8192 and you'll appreciate how much time is to be saved!
>time < nul & echo. & perl !.pl > output & time < nul & echo.
The current time is: 14:46:18.10
Enter the new time:
The current time is: 14:46:18.76
Enter the new time:
I'd say! :)
output = (((((((((((((X0*Y0)+(X1*Y1))+((X2*Y2)+(X3*Y3)))+...
| [reply] [d/l] [select] |
Re: Complicated Search and Replace
by runrig (Abbot) on Jun 27, 2005 at 18:38 UTC
|
With no error checking whatsoever (update: I left out the outermost pair of parens...oh well, ikegami's answer is better anyway):
use strict;
use warnings;
while(<DATA>) {
s/\@MAC\((\w+),(\w+),(\w+),(\d+)\)/mac($1, $2, $3, $4)/ge;
print;
}
sub mac {
my ($res, $x, $y, $n) = @_;
$n--;
my @mac = map { "($x$_*$y$_)" } 0..$n;
while (@mac > 2) {
@mac = map {
"($mac[$_]+$mac[$_+1])"
} grep {
!($_ % 2)
} 0..$#mac;
}
"$res = " . join("+", @mac);
}
__DATA__
@MAC(Output,X,Y,2);
@MAC(Result,X,Y,8);
| [reply] [d/l] |
Re: Complicated Search and Replace
by tlm (Prior) on Jun 27, 2005 at 18:50 UTC
|
use strict;
use warnings;
while ( <DATA> ) {
my ( $args ) = /\@MAC\((.*)\)/;
my ( $lhs, $v0, $v1, $e ) = split /,/, $args;
print "$lhs=\n", term( $v0, $v1, [0..$e-1] ), "\n";
}
sub term {
my $indices = pop;
my $n = $#$indices;
if ( $n ) {
my $m = int($n/2);
my @t = map term( @_, $_ ),
[ @{$indices}[0..$m] ], [ @{$indices}[$m+1..$n] ];
return "($t[0])+($t[1])";
}
else {
my ( $v0, $v1 ) = @_;
my $first = $indices->[0];
return "$v0$first*$v1$first";
}
}
__DATA__
@MAC(Result,A,B,2)
@MAC(output,X,Y,8)
__END__
Result=
(A0*B0)+(A1*B1)
output=
(((X0*Y0)+(X1*Y1))+((X2*Y2)+(X3*Y3)))+(((X4*Y4)+(X5*Y5))+((X6*Y6)+(X7*
+Y7)))
| [reply] [d/l] |
Re: Complicated Search and Replace
by TedPride (Priest) on Jun 27, 2005 at 19:38 UTC
|
I'm sort of wondering what you need all the parentheses for, given that order of operations makes them unnecessary. But here you are:
use strict;
use warnings;
$_ = join '', <DATA>;
s/\@MAC\((\w+),(\w+),(\w+),(\d+)\)/"$1 =\n".MAC($2,$3,$4)/eg;
print;
sub MAC {
my ($x, $y, $n) = @_;
$_ = ':';
$_ = "($_)+($_)" while ($n /= 2) != .5; $n = 0;
s/:/"$x$n*$y".$n++/eg;
return $_;
}
__DATA__
@MAC(Result,X,Y,1);
@MAC(Result,X,Y,2);
@MAC(Result,X,Y,4);
@MAC(Result,X,Y,8);
| [reply] [d/l] |
|
|
Yeah, if I was just running this as ordinary C code the parentheses would be superfluous. What's happening is that the parentheses are used to let a C-to-VHDL compiler get the idea of what kind of adder structure I want. I have a series of floating point multipliers at the base level. The output of two multipliers is summed together in a 2-input floating-point addition unit. The output of these additions are summed again in pairs in a further layer of adders. This continues with the adders halving each time until you finish up with a single adder and your output. This allows all the multiplication and addition to take place in parallel. Sweet, eh?
A0 B0 A1 B1 A2 B2 A3 B3
\ / \ / \ / \ /
(*) (*) (*) (*)
\ / \ /
\ / \ /
(+) (+)
\ /
\ /
\ /
\ /
\ /
\ /
(+)
|
Output
| [reply] [d/l] |
Re: Complicated Search and Replace
by dave_the_m (Monsignor) on Jun 27, 2005 at 18:29 UTC
|
print /^\s*\@MAC\((\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\d+)\s*\)\s*;\s
+*$/
? "$1 = (" . join('+',map "($2$_+$3$_)", 0..$4-1) . ");\n"
: $_
while (<>);
Dave. | [reply] [d/l] |
|
|
That doesn't even work for the examples provided by the OP. "What is important is getting the brackets in the right places", yet there are 4 pairs of brackets missing for n=8. Your solution only works for n=2 and n=4, and it's not even exact for n=2.
| [reply] |
|
|
whoops, wasn't reading OP closely enough.
Dave.
| [reply] |