Hi jag194u. I'm still not toolic, but here's an answer to your specific question along with a different general approach to your problem. (Of course, you don't give full input and output strings for your new $psprintf(...) variation and I've had to guess, but maybe I'm close.) However, I'm afraid I'm just leading you further down a dead-end street: what you really need is a real Verilog (it looks like) parser rather than a jury-rigged regex approach, but anyway... Give this a try, see what you think. You also don't say what Perl version you have available, and this needs version 5.10+.
File ToyVerilog.pm:
# ToyVerilog.pm 28may15waw
package ToyVerilog;
use 5.010; # needs (?|alternations) extended pattern of 5.10+
use warnings;
use strict;
use parent 'Exporter';
our @EXPORT = qw(xform);
our @EXPORT_OK = qw();
my $dq_body = qr{ [^"]* (?: \\. [^"]* )* }xms;
my $d_quote_plain = qr{ " $dq_body " }xms;
my $d_quote_dotted = qr{ " $dq_body (?: [.] $dq_body)+ " }xms;
my $identifier = qr{ \b [[:alpha:]] [[:alpha:]\d]* \b }xms;
my $number = qr{ \b \d+ \b }xms;
my $prime_h = qr{ \b \d+ ' h \d+ \b }xms;
my $param = qr{ $d_quote_dotted | $d_quote_plain | $identifier | $num
+ber | $prime_h }xms;
my $params = qr{ $param (?: \s* , \s* $param)* }xms;
my $func_name = qr{ \b [[:alpha:]]+ \b }xms;
my $plain_func = qr{ $func_name \s* [(] \s* $params \s* [)] \s* }xms;
my $dollar_func = qr{ \$ $plain_func }xms;
my $curly = qr{ { $params } }xms;
my $statement_a = qr{
# convert to e.g.:
# write_x("top.inst1.inst2.reg",32'h30,status,"string")
write_x \s* [(] \s*
($d_quote_dotted) \s* , \s*
($prime_h) \s* , \s*
($identifier) \s* , \s*
$d_quote_plain \s* [)]
}xms;
my $statement_b = qr{
# convert to e.g.:
# write_x("mod.ins5.ins7.val",{24'h0,4'h2,variable1,variable2},sta
+tus,"string")
write_x \s* [(] \s*
($d_quote_dotted) \s* , \s*
($curly) \s* , \s*
($identifier) \s* , \s*
$d_quote_plain \s* [)]
}xms;
my $statement_c = qr{
# convert to e.g.:
# write_x($psprintf("mod.ins[%d].ins[%d].val",1,2),{24'h0,4'h2,var
+iable1,variable2},status,"string")
write_x \s* [(] \s*
($dollar_func) \s* , \s*
($curly) \s* , \s*
($identifier) \s* , \s*
$d_quote_plain \s* [)]
}xms;
# subroutines ######################################################
sub xform {
my ($string,
) = @_;
$string =~ s{ (?| $statement_a | $statement_b | $statement_c) }
{writing.reg($1).write($3,$2)}xmsg;
return $string;
}
1; # inclusion success
File ToyVerilog.t:
use warnings;
use strict;
use Test::More
# tests => ?? + 1 # Test::NoWarnings adds 1 test
'no_plan'
;
use Test::NoWarnings;
use constant MULTI_LINE_PRE => <<'EOT';
write_x("top.inst1.inst2.reg",32'h30,status,"string"); foo
other stuff
bar write_x("mod.ins5.ins7.val",{24'h0,4'h2,variable1,variable2},statu
+s,"string");
some more things
baz write_x($psprintf("mod.ins[%d].ins[%d].val",1,2),{24'h0,4'h2,varia
+ble1,variable2},status,"string"); boff
whatever else
EOT
use constant MULTI_LINE_POST => <<'EOT';
writing.reg("top.inst1.inst2.reg").write(status,32'h30); foo
other stuff
bar writing.reg("mod.ins5.ins7.val").write(status,{24'h0,4'h2,variable
+1,variable2});
some more things
baz writing.reg($psprintf("mod.ins[%d].ins[%d].val",1,2)).write(status
+,{24'h0,4'h2,variable1,variable2}); boff
whatever else
EOT
BEGIN { use_ok 'ToyVerilog', qw(xform); }
VECTOR:
for my $ar_vector (
[ q{write_x("top.inst1.inst2.reg",32'h30,status,"string");},
q{writing.reg("top.inst1.inst2.reg").write(status,32'h30);},
'',
],
[ q{write_x("mod.ins5.ins7.val",{24'h0,4'h2,variable1,variable2},s
+tatus,"string");},
q{writing.reg("mod.ins5.ins7.val").write(status,{24'h0,4'h2,vari
+able1,variable2});},
'',
],
[ q{write_x($psprintf("mod.ins[%d].ins[%d].val",1,2),{24'h0,4'h2,v
+ariable1,variable2},status,"string");},
q{writing.reg($psprintf("mod.ins[%d].ins[%d].val",1,2)).write(st
+atus,{24'h0,4'h2,variable1,variable2});},
'',
],
[ MULTI_LINE_PRE,
MULTI_LINE_POST,
'',
],
# [ q{},
# q{},
# '',
# ],
) {
if (not ref $ar_vector) { # embedded comment if not test vector
note $ar_vector;
next VECTOR;
}
my ($statement, $expected) = @$ar_vector;
is xform($statement), $expected, $expected;
} # end for VECTOR
Output:
c:\@Work\Perl\monks\jag194u>perl ToyVerilog.t
ok 1 - use ToyVerilog;
ok 2 - writing.reg("top.inst1.inst2.reg").write(status,32'h30);
ok 3 - writing.reg("mod.ins5.ins7.val").write(status,{24'h0,4'h2,varia
+ble1,variable2});
ok 4 - writing.reg($psprintf("mod.ins[%d].ins[%d].val",1,2)).write(sta
+tus,{24'h0,4'h2,variable1,variable2});
ok 5 - writing.reg("top.inst1.inst2.reg").write(status,32'h30); foo
# other stuff
# bar writing.reg("mod.ins5.ins7.val").write(status,{24'h0,4'h2,variab
+le1,variable2});
# some more things
# baz writing.reg($psprintf("mod.ins[%d].ins[%d].val",1,2)).write(stat
+us,{24'h0,4'h2,variable1,variable2}); boff
# whatever else
#
ok 6 - no warnings
1..6
Give a man a fish: <%-(-(-(-<