首页 > 解决方案 > 如何找到没有大括号的 if 和 for 语句?

问题描述

我正在研究一个项目,其中一些iffor语句没有相关的括号,如下所示:

if(condition)
  single_line_statement;
for(int i=0;i<10;i++)
  single_line_statement;

我想找到这些陈述!

但是,由于存在具有两种不同括号样式的代码,这变得具有挑战性:

if(condition){
   stuff;
}

if(condition(a) && condition(b))
{
  stuff;
}

以及复杂的语句,例如(注意嵌套括号):

for (auto const &x : y)
{
    for (auto const &m : ted.bob())
    {
        if (m.n(o) != 0)
        {
            p[q] = true;
        }
        r["s"].push_back(rn.t(u));
    }
}

如何找到不带括号的ifand语句?for

标签: c++command-line

解决方案


为了解决这个问题,我创建了一个方便的花花公子脚本:

#!/bin/bash
find . -name '*.h' -o -name '*.cpp' | #Find all C++ files
  xargs pcregrep -A 1 -nHM '\b(?:if|for)\s*(\(([^()]++|(?1))*\))(?!.*{|.*\n.*{)'

这会找到所有 C++ 文件,然后使用 Perl 兼容正则表达式将每个文件的内容作为一个长行来检查。此表达式使用递归(?1)来提取(condition)以下ifandfor语句和.字符以匹配不是换行符的字符和\n常量以匹配换行符。Negative-lookahead(?!...)用于查找没有大括号的行。

正则表达式可以在这里在线测试。

输出如下所示:

./dir1/file1.cpp:845:        if (!a)
./dir1/file1.cpp-846-            std::cout << "a not found!" << std::endl;
--
./dir2/file2.cpp:20:    if (b == NULL)
./dir2/file2.cpp-21-        throw std::runtime_error("b was NULL");

由于该脚本实际上并不解析 C++,因此在某些情况下它会出现异常。例如,它会错过这个:

if (condition) // An example {
  statement;

这个答案可以clang-tidy提供一个完整的检查,代价是必须合并clang-tidy到一个人的构建系统中。


推荐阅读