我想对与C / C ++注释和预处理器指令兼容的汇编文件进行一些重新分解。
不幸的是我不能使用像Astyle这样的重构工具。我必须手动解析我的文件。
我的重构算法迭代文件的每一行,如下所示:
while(<FH>)
{
next if isComment($_);
$count += s/$search/$replace/; # A refactoring rule
$count += arithmetic($_); # R1=R2+3*4; --> r1 = r2 + 3 * 4;
...
$out .= $_;
}
if($count)
{
open my $fh ">$filename";
print $fh $out;
close $fh;
}
使用这种方法我无法准确检测到评论行。因此,我实施的计数器指向每个/*
,并减少每个*/
。如果计数器大于0,我忽略该行。
不幸的是,在这种情况下,此方法不起作用:
/* /* <-- Not allowed */ /* */
计数器将等于1,而它应该等于0.
所以我正在寻找一种准确的方法来检测注释块并忽略它们。有没有可以帮助我的包裹或模块?
答案 0 :(得分:1)
您必须更详细地解析代码,因为评论字符可能位于字符串中或#ifdef
中。
也许您应该运行预处理器来为您准备代码。对于GCC预处理器,请查看How do I run the GCC preprocessor to get the code after macros like #define are expanded?。
您可能希望将预处理的代码输出到stdout
并在perl代码中打开一个管道。
要完全正确地执行它,您还必须解析所有包含文件。想象一下以下(非常糟糕但有效)的代码:
/*
*/
#include <stdio.h>
int main() {
#include "inc1.h"
printf("Ha!\n");
#include "inc2.h"
}
答案 1 :(得分:0)
最终我发现这个解决方案效果很好。我全局识别所有评论区块,并将其替换为标记/*@@n@@*/
,其中n
是一个数字。
处理完成后,我可以恢复原始评论。
#!/usr/bin/env perl
use 5.014;
use strict;
use warnings;
# C/C++ Comment detection
my $re = qr{(
/\* ## Start of /* ... */ comment
[^*]*\*+ ## Non-* followed by 1-or-more *'s
(?:
[^/*][^*]*\*+
)*
/
|//.* ## // ... comment
|"[^"]*" ## A souble quoted string
|'[^"]*' ## A simple quoted string
)}mx;
my $i = 0;
my @comments = ();
while(<$fh>) {
return unless -f;
my $filename = $_;
# Read whole file
open my $fh, '<', $filename or die "Unable to open $filename";
$_ = do {local $/ = undef; <$fh>};
# Store C/C++ comments and replace them with markers
$i = 0;
@comments = ();
s|$re|&store($1)|eg;
# Do the processing
...
# Restore C comments
$i = 0;
for my $comment (@comments) {
my $s = quotemeta("/*@@".$i++."@@*/");
s|$s|$comment|g;
}
}
sub store {
my $marker = "/*@@".$i."@@*/";
$comments[$i] = shift;
$i++;
$marker;
}