object:把一個bench文件裏面的字符串替換成新的合適的字符串,如N1,N2...等
tools:awk,sed,bash
一個典型的bench例子如下:
# comment
INPUT(INPUT_NODE)
OUTPUT(OUTPUT_NODE)
SOME_NODE = ADD( INPUT_NODE, OUTPUT_NODE )
因此替換規則是,把INPUT_NODE換為N1,OUTPUT_NODE-> N2,SOME_NODE->N3,
並且它們所有隨後的出現也要替換。
思路:
- 使用awk做一個parser,利用其关联数组的功能存储新出现的node name,并分配一個新名字。當parse結束后,就得到了一份字典(map)
- 利用字典構造替換正則運算式,用sed進行全局替換。
- 編寫shell script把所有工作整合起來(glue)
BEGIN{
counter=0;
gate_names_str = "DFF|OR|ADD|NAND|NOR|NOT|AND|BUF"
split(gate_names_str,gate_names,"|")
split_regex = "[ ,)(=]"# gate_names
#for( i in gate_names ) print gate_names[i];
}
function add2dict(node_name){
if( dict[node_name] == "" ){
dict[node_name]=sprintf("N%d",counter);
counter++;
#print node_name " " dict[node_name]
# beautiful output
printf("%-20s%s\n",node_name,dict[node_name]);
}
}
/#/{
# do nothing
}
/INPUT/ {
# store each gate name into dict from INPUT(...)
len = index($1,")")-7;
str = substr($0,7,len);
add2dict(str);
}
/OUTPUT/ {
# store each gate name into dict from OUTPUT(...)
len = index($1,")")-8;
str = substr($0,8,len);
add2dict(str);
}
/=/{
# split using `='
split($0,names,split_regex)
for(i in names){
if(names[i]=="") continue;
# do not handle gate names
ignore=0;
for(j in gate_names){
if( names[i] == gate_names[j] ){
ignore=1;
break;
}
}
if(ignore==1) continue;
add2dict(names[i]);
}
}
END{
#for(i in dict) print i " " dict[i]
}
主要的流程是,對INPUT,OUPUT, xxx = op(yyy,zzz,...) 三種不同的pattern做解析,
并extract出裏面的單詞,存入字典,注意要去除重複,並且不能把op存入字典。
awk的關聯数组真的很好用,并且for i in array這種for循环也非常方便。
split函数可以方便地把一个字符串根据split field分割并保存到数组里,并且还支持正则表达式的split field
然后是 生成 sed 的string, 这里是脚本内容:
#!/bin/bash
if [ $# -lt 1 ];then
echo "Usage: ./replace_name.sh bench_name"
exit 1
fi
# generate dictionary
awk -f gen_dict.awk "$1" > tmp
sort tmp > dict
# construct sed expression
echo -n "" > exp.sed
while read line
do
from=${line%% *}
to=${line##* }
echo "s/${from}/${to}/g ">> exp.sed
done < "dict"
sed -f exp.sed "$1"
# remove extra file
rm -rf dict exp.sed tmp
其中 while read line ... done < "dict" 那段實現了從文件里逐行讀取。
而bash 的 字符串替換功能也很方便地把每行的兩個field存到不同变量里。
注意这里如果有多个field的话,也许用cut或awk来实现比较方便。
最后,针对每行生成一个替换的正则表达式,并提供给sed进行替换。
#END
No comments:
Post a Comment