1

我正在处理一项任务,而且我对 Perl 真的很陌生。真的不是很懂。你们能指导我提取这三种文件(C、C++ 和 Java)的注释和函数名吗?

我已经尝试过这个:

use strict;
use warnings;
use File::Basename;
use File::Find;
use File::Slurp;
use Regexp::Common qw /comment/;
    my $fileName = "a.java";
    my $wordsIn = "";
    my $wordsIdentifier="";
    my $numRemoved = 0;

    #$wordsOut = `xscc.awk extract=comment prune=copyright $fileName`;
    $wordsIn = read_file($fileName) ;
    # Find all matches of comments, and put them into @arr
    my @arr = $wordsIn =~  m/$RE{comment}{Java}/g;
    my $wordsOut = join(" ", @arr);
    print "Comments:\n";
    print $wordsOut;
    $wordsIn =~ s/$RE{comment}{Java}//g;
    print "Identifiers:\n";
    print $wordsIn;

它完美地获得了评论(即使我不知道如何!),但是为了检索标识符和方法名称,我应该为 $RE{comment}{Java} 做什么

问候 Ehsan

4

2 回答 2

2

Regexp::Common 没有为它提供正则表达式,所以你必须自己做。由于可能格式的数量,这非常复杂。例如,在 C 中,您需要搜索:

<type> <identifier - save this> (<comma-separated list of types and identifiers>)
{

但是你不一定知道所有可能的类型(包含文件中的 typedefs),并且在可选的空格和注释之间,更不用说旧式的函数定义,可能很难捕捉到每一种情况。

事实证明,为 C 语言编写词法分析器实际上非常困难,而且当您不知道诸如 typedef 之类的东西可能包含很多包含文件并且您不实现整个预处理器时,这更加困难。不适用于您的情况的常见示例是(A)*B,如果不检查 typedef 的所有包含,您无法判断它是标量取消引用的乘法还是类型转换。

于 2012-09-29T02:25:52.333 回答
2

有两种基本方法:使用预先存在的解析器或使用编译器为您提供所需的信息。

对于 C,有C::Scan从 C(以及许多 C++)中获取函数声明(以及更多)。或者您可以让gcc为您提供所需的信息。

至于Java,那就更难了。一种可能性是弄清楚Inline::Java是如何做到的。或者,您可以尝试使用Eclipse 中的解析器

挖掘现有“足够好”正则表达式的可能性来自TextMate或其他执行语法突出显示的编辑器。我提到 TextMate 是因为我发现它的语言解析是最容易理解的。您可能可以挖掘他们的 Java 包以获取必要的正则表达式。

如果这只是一个正则表达式练习,那么教训是这种事情对于正则表达式来说太复杂了。对于语言,您需要该语法的语法和解析器。

于 2012-09-29T02:44:52.933 回答