bit幅表現→16進数表現変換

入力テキストは以下の通りの表現。この表現は32bitアドレスとbit幅を表現している。この有効bit幅表現を32bit幅の16進数表現に変換したい。

# addr.txt
# This scripts expresses the valid bit range. (address[bit-h:bit-l]).
10001010
20002020[15:3]
30003030[23-10]
40004040[:1]
  • ビット幅表記が無いときや、片側表記の時は全ビット(32bit)有効。
  • ビット幅表記は"[","]"中にある。bit有効範囲表記は":"もしくは"-"で区切られている。右側がLSB,左側がMSB側の有効範囲

以下の様に書いてみた。一応動いているようだ。

#!/usr/bin/perl
#$Id:$
#This scan parses address and valid bits.

open(FILE,"addr.txt");

sub scan_bits{
    my($start,$end) = @_;

    my($return_num) = 0;

    if($start eq "x"){
	return 0xFFFF_FFFF;
    }else{

	if(($start < 0)||($end < $start)||$end > 31){
	    print "Number Error! (start= $start, end= $end)\n";
	    exit(-1);
	}

	if($end eq "x"){
	    $end = 31;
	}

	for($i=$start;$i<$end;$i++){
	    $return_num |= 1<<$i;
	}

    }
    return $return_num;
}

while(<FILE>){

    next if(/^\#/); #skip comment lines

    if(/([0-9A-Fa-f]{8})/){
	$addr=$1;
	if(/[0-9A-Fa-f]{8}\[(\d+)[\:\-](\d+)\]/){
	    $start = $2;
	    $end=$1;
	    $return_num = &scan_bits($start,$end);
	}else{
	    $start = "x";
	    $end = "x";
	    $return_num = &scan_bits($start,$end);
	}

	print "addr=$addr\n";
#	print "start= $start end= $end\n";
	printf "return_num= %08X\n",$return_num;
    }
}

close(FILE);

I take a memo about the program that converts the valid bid range to hexadecimal form.
I could convert by the above script.