将算术表达式替换为表达式参数的printf

时间:2012-06-19 16:41:30

标签: c text sed awk

我正在使用多面体编译器生成相当难以理解的代码,这里有一个小样本:

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应该可以做这样的替代,但欢迎任何其他语言的建议!

更新算术表达式可以是任何算术表达式,例如:

b[t3][t4]=0.2*(a[t3][t4]+a[t3][t4-1]+a[t3][1+t4]+a[1+t3][t4]+a[t3-1][t4]);;

2 个答案:

答案 0 :(得分:2)

<强>代码:

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

<强>说明:

  • awk '/\[/ { ........; next; }1'会在找到........字符的任意行执行[,否则会打印该行。
  • sub(/^ */, "");修剪当前行的前导空格字符
  • sub(/;*$/, "");修剪当前行的尾部分号字符
  • 接下来是连接5位的print语句
  • gensub("\\[[^]]*\\]", "[%d]", "g")返回当前行的副本,其中任何方括号内的语句都替换为[%d]。请注意,嵌套的方括号会破坏它。另请注意,与sub相反,gensub命令实际上不会修改当前行。
  • gensub("[^\\[]*\\[([^]]*)\\][^\\[]*", ",\\1", "g")也会获取当前行的副本,对于它找到的每个方括号表达式,它会执行以下三项操作:
    • [^\\[]*删除了前导非[字符
    • \\[([^]]*)\\]匹配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);

答案 1 :(得分:1)

分割表达式:

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"等等。分割中的正则表达式看起来有点奇怪,但基本上它只是分为[]。显然,这是非常脆弱的,完整的解析器是最好的,但这应该有所帮助。