[英]Replace arithmetic expression with printf of expression arguments
我正在使用多面体编译器生成相当难以理解的代码,这里有一个小样本:
for (t2=2*t1;t2<=min(floord(2*T+N-3,32),floord(64*t1+N+61,32));t2++) {
for (t3=max(ceild(32*t2-N-27,32),2*t1);t3<=min(min(floord(2*T+N-3,32),floord(64*t1+N+61,32)),floord(32*t2+N+27,32));t3++) {
if ((t1 <= floord(32*t3-N+1,64)) && (t2 <= t3-1)) {
if ((N+1)%2 == 0) {
for (t5=max(32*t2,32*t3-N+4);t5<=32*t2+31;t5++) {
a[-32*t3+t5+N-2][N-2]=b[-32*t3+t5+N-2][N-2];;
}
}
}
if ((t1 <= floord(32*t2-N+1,64)) && (t2 >= t3)) {
if ((N+1)%2 == 0) {
for (t6=max(32*t3,32*t2-N+4);t6<=min(32*t2,32*t3+31);t6++) {
a[N-2][-32*t2+t6+N-2]=b[N-2][-32*t2+t6+N-2];;
}
}
}
我试图通过使用数组索引的printf在生成的代码中转换算术表达式来调试编译器的一部分,例如,这个表达式:
a[-32*t3+t5+N-2][N-2]=b[-32*t3+t5+N-2][N-2];;
应该成为这个printf:
printf("a[%d][%d] = b[%d][%d]\n",-32*t3+t5+N-2,N-2,-32*t3+t5+N-2,N-2);
我开始尝试使用awk并生成这个简单的程序,该程序识别要修改的字符串并让程序的其余部分保持不变:
awk '{if ($0 ~ "^[ ]*[a,b]") print "printf("; else print $0;}'
但是,我不知道如何解析算术表达式以便在删除数组访问的索引时保留其结构。 我尝试了一段时间,但我现在卡住了。 awk应该可以做这样的变种,但欢迎任何其他语言的建议!
update算术表达式可以是任何算术表达式,例如:
b[t3][t4]=0.2*(a[t3][t4]+a[t3][t4-1]+a[t3][1+t4]+a[1+t3][t4]+a[t3-1][t4]);;
码:
awk '/\[/ { \
sub(/^ */, ""); \
sub(/;*$/, ""); \
print \
"printf(\"" \
gensub("\\[[^]]*\\]", "[%d]", "g") \
"\"" \
gensub("[^\\[]*\\[([^]]*)\\][^\\[]*", ",\\1", "g") \
");" \
; \
next; \
}1'
说明:
awk '/\\[/ { ........; next; }1'
awk '/\\[/ { ........; next; }1'
将在找到[
字符的任何行上执行........
,否则将打印该行未触及。 sub(/^ */, "");
修剪当前行的前导空格字符 sub(/;*$/, "");
修剪当前行的尾部分号字符 print
语句 gensub("\\\\[[^]]*\\\\]", "[%d]", "g")
返回当前行的副本,其中任何方括号语句都替换为[%d]
。 请注意,嵌套的方括号会破坏它。 另请注意,与sub
相反, gensub
命令实际上不会修改当前行。 gensub("[^\\\\[]*\\\\[([^]]*)\\\\][^\\\\[]*", ",\\\\1", "g")
也取当前的副本线,并且对于它找到的每个方括号表达式,它做了3件事:
[^\\\\[]*
删除前导非[
字符 \\\\[([^]]*)\\\\]
匹配square-bracketed表达式, ",\\\\1"
将其替换为逗号字符,后跟方括号内的内容 [^\\\\[]*
删除尾随的非[
字符(直到下一个方括号表达式或行尾) [
字符在2平方括号表达式之间是多余的,但在行的开头和结尾处很有用。 输入:
for (t2=2*t1;t2<=min(floord(2*T+N-3,32),floord(64*t1+N+61,32));t2++) {
for (t3=max(ceild(32*t2-N-27,32),2*t1);t3<=min(min(floord(2*T+N-3,32),floord(64*t1+N+61,32)),floord(32*t2+N+27,32));t3++) {
if ((t1 <= floord(32*t3-N+1,64)) && (t2 <= t3-1)) {
if ((N+1)%2 == 0) {
for (t5=max(32*t2,32*t3-N+4);t5<=32*t2+31;t5++) {
a[-32*t3+t5+N-2][N-2]=b[-32*t3+t5+N-2][N-2];;
}
}
}
if ((t1 <= floord(32*t2-N+1,64)) && (t2 >= t3)) {
if ((N+1)%2 == 0) {
for (t6=max(32*t3,32*t2-N+4);t6<=min(32*t2,32*t3+31);t6++) {
a[N-2][-32*t2+t6+N-2]=b[N-2][-32*t2+t6+N-2];;
}
}
}
b[t3][t4]=0.2*(a[t3][t4]+a[t3][t4-1]+a[t3][1+t4]+a[1+t3][t4]+a[t3-1][t4]);;
输出:
for (t2=2*t1;t2<=min(floord(2*T+N-3,32),floord(64*t1+N+61,32));t2++) {
for (t3=max(ceild(32*t2-N-27,32),2*t1);t3<=min(min(floord(2*T+N-3,32),floord(64*t1+N+61,32)),floord(32*t2+N+27,32));t3++) {
if ((t1 <= floord(32*t3-N+1,64)) && (t2 <= t3-1)) {
if ((N+1)%2 == 0) {
for (t5=max(32*t2,32*t3-N+4);t5<=32*t2+31;t5++) {
printf("a[%d][%d]=b[%d][%d]",-32*t3+t5+N-2,N-2,-32*t3+t5+N-2,N-2);
}
}
}
if ((t1 <= floord(32*t2-N+1,64)) && (t2 >= t3)) {
if ((N+1)%2 == 0) {
for (t6=max(32*t3,32*t2-N+4);t6<=min(32*t2,32*t3+31);t6++) {
printf("a[%d][%d]=b[%d][%d]",N-2,-32*t2+t6+N-2,N-2,-32*t2+t6+N-2);
}
}
}
printf("b[%d][%d]=0.2*(a[%d][%d]+a[%d][%d]+a[%d][%d]+a[%d][%d]+a[%d][%d])",t3,t4,t3,t4,t3,t4-1,t3,1+t4,1+t3,t4,t3-1,t4);
拆分表达式:
a[N-2][-32*t2+t6+N-2]=b[N-2][-32*t2+t6+N-2];
进入数组,使用split:
split( $0, ar, "[][]" )
在这个调用之后, ar[2] = "N-2"
, ar[4] = "-32*t2+t6+N-2"
等。分割中的正则表达式看起来有点奇怪,但基本上它只是分裂在[
或]
。 显然,这是非常脆弱的,完整的解析器是最好的,但这应该有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.