c - 用表达式参数的 printf 替换算术表达式

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

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

最佳答案

代码:

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

解释:

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

关于c - 用表达式参数的 printf 替换算术表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11105489/

相关文章:

linux - 如何在 linux 中每第 n 行对数据进行排序?

c - 数组访问算法是在编译时还是运行时完成的?

c - 检查输入字符串是整数还是 float 的函数?

c - 在 autotools 项目中添加 CFLAG(例如 -std=gnu99)的位置

c - 在 C 中读取具有不同扩展名的 .txt 文件

linux - 在用双引号替换定界符时处理数据

objective-c - 在 OS X 中以编程方式模拟/切换 CAPS LOCK

C++ 理解类和构造函数

javascript - 删除 js 变量中 ( 和 ) 之间的文本

linux - 如何区分带后缀和不带后缀的文件名?