1

我正在使用一个多面体编译器,该编译器会产生非常不可读的代码,这是一个小示例:

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;}'

但是,我不知道如何解析算术表达式以便在删除数组访问的索引时保留其结构。我尝试了一个while循环,但我现在被卡住了。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]);;
4

2 回答 2

2

代码:

awk '/\[/ { \
    sub(/^ */, ""); \
    sub(/;*$/, ""); \
    print \
        "printf(\"" \
        gensub("\\[[^]]*\\]", "[%d]", "g") \
        "\"" \
        gensub("[^\\[]*\\[([^]]*)\\][^\\[]*", ",\\1", "g") \
        ");" \
    ; \
    next; \
}1'

说明:

  • awk '/\[/ { ........; next; }1'........在找到[字符的任何行上执行,否则将打印未触及的行。
  • sub(/^ */, "");从当前行修剪前导空格字符
  • sub(/;*$/, "");修剪当前行的拖尾分号字符
  • 接下来是一个print连接 5 位的语句
  • gensub("\\[[^]]*\\]", "[%d]", "g")返回当前行的副本,其中任何方括号语句都替换为 with [%d]。请注意,嵌套的方括号会破坏这一点。另请注意,与 相反sub,该gensub命令实际上并不修改当前行。
  • gensub("[^\\[]*\\[([^]]*)\\][^\\[]*", ",\\1", "g")还获取当前行的副本,并且对于它找到的每个方括号表达式,它会做 3 件事:
    • [^\\[]*删除前导非[字符
    • \\[([^]]*)\\]匹配方括号表达式,并将",\\1"其替换为逗号字符后跟方括号内的内容
    • [^\\[]*删除尾随的非[字符(直到下一个方括号表达式或行尾)
  • 请注意,删除两个[方括号表达式之间的前导和尾随非字符是多余的,但在行的开头和结尾很有用。

输入:

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);
于 2012-06-21T17:27:23.073 回答
1

拆分表达式:

a[N-2][-32*t2+t6+N-2]=b[N-2][-32*t2+t6+N-2];

成一个数组,使用拆分:

split( $0, ar, "[][]" )

在此调用之后ar[2] = "N-2"ar[4] = "-32*t2+t6+N-2", 等。 split 中的正则表达式看起来有点奇怪,但基本上它只是在[or上进行拆分]。显然,这非常脆弱,最好使用完整的解析器,但这应该会有所帮助。

于 2012-06-19T17:01:39.193 回答