2

我正在寻找 awk 中的脚本,它将检查它是否有正确的括号放置。使用的括号是 {} [] 和 () 每个括号都应该闭合,括号不能混用,非法示例:( [ ) ]

4

2 回答 2

2

如果您尝试做的事情适用于通用语言,那么这是一个不平凡的问题。

首先,您将不得不担心注释和字符串。如果您想在使用正则表达式的编程语言上检查这一点,这将使您的任务再次变得更加困难。

所以在我进来就你的问题给你任何建议之前,我需要知道你的问题领域的局限性。如果您可以保证没有字符串、注释和正则表达式需要担心 - 或者更一般地说,在代码中除了您正在检查它们是否平衡的用途之外,括号可能没有其他地方使用 - 这将让生活变得简单很多。

了解您要检查的语言会很有帮助。


如果我假设没有噪音,即所有括号都是有用的括号,我的策略将是迭代的:

我会简单地查找并删除所有内部括号对:那些内部不包含括号的。这最好通过将所有行折叠成一条长行来完成(并找到一种机制来添加行引用,如果您需要获取该信息)。在这种情况下,搜索和替换非常简单:

它需要一个数组:

B["("]=")"; B["["]="]"; B["{"]="}"

并通过这些元素循环:

for (b in B) {gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)}

我的测试文件如下:

#!/bin/awk

($1 == "PID") {
  fo (i=1; i<NF; i++)
  {
    F[$i] = i
  }
}

($1 + 0) > 0 {
  count("VIRT")
  count("RES")
  count("SHR")
  count("%MEM")
}

END {
  pintf "VIRT=\t%12d\nRES=\t%12d\nSHR=\t%12d\n%%MEM=\t%5.1f%%\n", C["VIRT"], C["RES"], C["SHR"], C["%MEM"]
}

function count(c[)
{
  f=F[c];

  if ($f ~ /m$/)
  {
    $f = ($f+0) * 1024
  }

  C[c]+=($f+0)
}

我的完整脚本(没有行引用)如下:

cat test-file-for-brackets.txt | \
  tr -d '\r\n' | \
  awk \
  '
    BEGIN {
      B["("]=")";
      B["["]="]";
      B["{"]="}"
    }
    {
      m=1;
      while(m>0)
      {
        m=0;
        for (b in B)
        {
          m+=gsub("[" b "][^][(){}]*[" B[b] "]", "", $0)
        }
      };
      print
    }
  '

该脚本的输出在括号的最里面非法使用处停止。但请注意:1/ 此脚本不适用于注释、正则表达式或字符串中的括号,2/ 它不会报告问题在原始文件中的位置,3/ 尽管它会删除所有平衡对,但它会停止在最里面错误条件并保留所有 englobbing 括号。

第 3 点/ 可能是一个可利用的结果,尽管我不确定您想到的报告机制。

第 2 点/ 相对容易实现,但需要花费几分钟以上的时间才能完成,所以我将由您自己解决。

第 1 点/ 是一个棘手的问题,因为您进入了一个全新的领域,有时是嵌套的开头和结尾,或者特殊字符的特殊引用规则……

于 2010-12-12T04:48:37.053 回答
1

您必须逐个字符地读取文件。构建一堆可见的开括号。当您看到一个右括号时,您可以将匹配的左括号从堆栈中弹出,或者记录一个括号不匹配的错误。

awk 不是这项工作的正确工具。我会使用通用脚本语言(Perl/Tcl/etc)。

于 2010-04-19T13:16:33.957 回答