See: https://www.oreilly.com/library/view/mastering-perl/9780596527242/ch02.html
I'm having some trouble getting the perl Global Match Anchors \G to work with my input file proved below with my perl code... I would have thought \G keeps picking up where it left off in the previous match and matches from that position in the string?
note, if i uncomment these two line it works:
#!/bin/perl
$vlog = "out/tb_asc.sv";
open(my $F, "$vlog") || die("cannot open file: $vlog\n");
@lines = <$F>;
chomp(@lines);
$bigline = join("\n", @lines);
close($F);
$movingline = $bigline;
print ">> << START\n";
$moving = $bigline;
$moving =~ s|//.*$||mg;
$moving =~ s|\s $||mg;
while(1) {
# Blank Linke
if ($moving =~ /\G\n/g) {
#$moving = substr $moving, $ [0] 1; # <= doesn't \G anchor imply this line?
next;
}
# Precompiler Line
if ($moving =~ /\G\s*`(\w )(\s (.*))?\n/g) {
$vpccmd = $1;
$vpcarg1 = $3;
#$moving = substr $moving, $ [0] 1;
print "vpc_cmd($vpccmd) vpc_arg1($vpcarg1)\n";
next;
}
$c = nextline($moving);
print "\n=> processing:[$c]\n";
die("parse error\n");
}
sub nextline($) {
@c = split(/\n/, $moving);
$c = $c[0];
chomp($c);
return $c;
}
sample input file: out/tb_asc.sv
`timescale 1ns / 1ps
`define DES tb_asc.DES.HS86.CORE
`ifdef HS97_MODE
`define SER_DUT HS97
`ifndef HS78_MODE
`define SER_DUT HS78
`else //1:HS78_MODE
`define SER_DUT HS89
`define SER tb_asc.SER.`SER_DUT.CORE
`ifdef MULTIPLE_SERS
`define SER_1 tb_asc.SER_1.`SER_DUT.CORE
`define SER_2 tb_asc.SER_2.`SER_DUT.CORE
`define SER_3 tb_asc.SER_3.`SER_DUT.CORE
`else //1:MULTIPLE_SERS
`define SER_1 tb_asc.SER.`SER_DUT.CORE
`define SER_2 tb_asc.SER.`SER_DUT.CORE
`define SER_3 tb_asc.SER.`SER_DUT.CORE
`define REPCAPCAL DIGITAL_TOP.RLMS_A.REPCAL.U_REPCAPCAL_CTRL
`define MPU_D POWER_MGR.Ism.por_pwdnb_release
`define DFE_OUT RXD.EC.Eslicer.QP
`define DFE_OUT_SER RXD.EC.Eslicer.QP
//beg-include-1 ser_reg_defs_macros.sv
//FILE: /design/proj/hs89/users/HS89D-0A/digital/modules/cc/src/ser_reg_defs_macros.sv
`define CFG_BLOCK "CFG_BLOCK"
`define DEV_ADDR "DEV_ADDR"
`define RX_RATE "RX_RATE"
`define TX_RATE "TX_RATE"
`define DIS_REM_CC "DIS_REM_CC"
`define DIS_LOCAL_CC "DIS_LOCAL_CC"
NOTE: this version works but doesn't use \G:
while(1) {
# Blank Linke
if ($moving =~ /\A$/m) {
$moving = substr $moving, $ [0] 1;
next;
}
# Precompiler Line
if ($moving =~ /\A\s*`/) {
$moving =~ /\A\s*`(\w )(\s (.*))?$/m;
$vpccmd = $1;
$vpcarg1 = $3;
$moving = substr $moving, $ [0] 1;
print "vpc_cmd($vpccmd) vpc_arg1($vpcarg1)\n";
next;
}
$c = nextline($moving);
print "\n=> processing:[$c]\n";
die("parse error\n");
}
I prefer to do this using \G because substr uses a lot of CPU time with a large input file.
CodePudding user response:
The bit you're missing is that is that an unsuccessful match resets the position.
$ perl -Mv5.14 -e'$_ = "abc"; /./g; /x/g; say $& if /./g;'
a
Unless you also use /c
, that is.
$ perl -Mv5.14 -e'$_ = "abc"; /./gc; /x/gc; say $& if /./gc;'
b
CodePudding user response:
When your match fails, In the link to Mastering Perl that you provide, I wrote:
I have a way to get around Perl resetting the match position. If I want to try a match without resetting the starting point even if it fails, I can add the /c flag, which simply means to not reset the match position on a failed match. I can try something without suffering a penalty. If that doesn’t work, I can try something else at the same match position. This feature is a poor man’s lexer.
My example that I think you are trying to use has /gc
on all the matches using \G
.