c++ - 想要获取perl在c、cpp或.h的多个文件中定义的函数名称

标签 c++ c regex perl

c、cpp 和 .h 文件语法示例 cpp文件

{< //--------------------------------------------------------------------------------------------
// FORWARD DECLARATION
//--------------------------------------------------------------------------------------------


Result_t
dumpAdSidToLocalGroupsAndPriv(uint32_t                             vserverId,
                              const Asid&                          userAsid,
                              AdSidToLocalGroupsAndPrivCacheEntry& valEntry,
                              const struct timeval&                entryTime)
{
-----------------------
}

//---------------------------------------------------------------------------/>}

.cc 文件函数定义示例

{
smdb_error ##return type
hosts_byname_iterator::apply_imp(const apply_info_t &info)
{
--------
}

对于其他 c 和 .h 也是如此

我想要得到的是使用 Perl 正则表达式,我只想将这些函数名称作为输出。 我将这些文件作为该 Perl 文件的输入传递。我想将多个文件作为输入传递给该 Perl 文件。

我使用的代码是这样的:

{
use strict;
use warnings;

my $filename = $ARGV[0];  
my $filename1 ='report.txt';
open(my $fh1, '>>', $filename1) or die "Could not open file ".$filename;
print $fh1 "\n Output file \n";
my $data = do {
open my $fh, '<', $filename or die $!;
local $/;
<$fh>;
};

my $count = 0;
while ($data =~ /(.*::.*/g ) {
    my $word = $1;
    print $fh1 $word."\n";
    ++$count;
    print "%2d: %s\n", $count, $word;
}
}

最佳答案

你尝试做的事情是危险的。

正则表达式的功能不足以解析像 C++ 这样复杂的语言。你可以找到精彩的讨论here (虽然在这种情况下是关于 HTML 的,但是那里所说的仍然适用)。正确的 C++ 解析需要一个成熟的解析器。根据我自己研究这个主题时到处读到的一些评论,C++ 实际上非常困难,以至于大多数商业解析器都无法正确完成它,因为有太多的边缘情况。然而,正如我链接的答案中所建议的,在某些情况下尝试基于正则表达式的方法是可能的。但你必须确保你的数据遵循某些模式,通常很难做出这样的假设。

也就是说...您的代码甚至无法编译。你必须像这样修复你的正则表达式:

while ($data =~ /(.*::.*)/g ) {

但这意味着你只会找到属于类成员的函数,而且你还会得到一些误报,因为 class::function 语法也可以用于调用函数,而不仅仅是定义它们,所以我' d 在 .h 文件中查找声明末尾的分号。命名空间也使用相同的 :: 表示法。当我试图编写自己的正则表达式来解析 C++ 时(在发现它无法完成之前,如上所述),我试图找到这样的东西:

#!/usr/bin/perl
use strict;
use warnings;

my $data = "int& myClass::Function1();\n"
         . "void * me::function2(const int& temp, double a, char[] b);\n"
         . "double** class::function_3 (int[] array, int& result);\n";

while ($data =~ /\s*(\w+([\s&\*]*))((::)?((\w+)::)?(\w+)\s*\(([^)]*)\)\s*;)/gs ) {
    my $return_type = $1;
    my $class = $6;
    my $function_name = $7;
    my $arguments = $8;
    print "return_type   = $return_type\n";
    print "class         = $class\n";
    print "function_name = $function_name\n";
    print "arguments     = $arguments\n";
}

正如你所看到的,这个正则表达式已经相当复杂了,而且仍然有很多情况它无法捕获(命名空间、模板、每行可能有一个参数+注释的多行函数怎么样?并且很快...)。如果您真的想这样做,请尝试基于测试的方法:

  1. 分析数据的格式,即您要考虑的函数名称(例如:它们是否使用命名空间?它们是否返回引用、指针等?在这种情况下,它们之间是否有空格) ?)
  2. 创建一个测试套件,即名为 function1、function2、function3 的函数列表...确保每种可能的语法都有一个案例(这是困难的部分,因为如何确保您都考虑过了吗?)
  3. 编写一个涵盖尽可能多情况的正则表达式。如果您无法用一个循环覆盖所有这些循环,请考虑使用多个循环(在我给出的示例中,它将是多个 while 循环)。每次有匹配时,都将其打印出来。最后,检查您是否已找到测试中的所有函数。

如果您能做到所有这些,并且在定义测试用例方面做得非常好,那么您就能成功。但让我再说一遍,正则表达式不是解决此问题的正确工具,它们仅在有限的情况下起作用,甚至确定它们是否在您的情况下起作用也很困难。

再次:考虑一个解析器!

关于c++ - 想要获取perl在c、cpp或.h的多个文件中定义的函数名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28940621/

相关文章:

c - 在C中逐行读取并识别元素

编译器优化不编译常量?

php - 分割正则表达式php

java - 单个 Java 正则表达式中的多个匹配项

c++ - 在子窗口的 OnShowWindow 中将焦点设置到父窗口不起作用

c++ - 类中定义的方法的地址

c++ - pthreads 的 Makefile

java - 在 Java 中无法匹配 myname@myemail.edu.in

C++字符串输出笑脸

C++ 在运行时修改资源