Home > Mobile >  Global Match Anchors \G: rolling lover over an input file
Global Match Anchors \G: rolling lover over an input file

Time:11-09

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.

  •  Tags:  
  • perl
  • Related