2010-04-14 62 views
1

我正在運行讀取文件的代碼,執行一些解析,但需要忽略所有註釋。 有很好的解釋如何進行呢,像答案How can I strip multiline C comments from a file using Perl?當我使用Perl處理C源文件時,如何忽略C註釋?

$/ = undef; 
$_ = <>; 
s#/\*[^*]*\*+([^/*][^*]*\*+)*/|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^/"'\\]*)#defined $2 ? $2 : ""#gse; 
print; 

我的第一個問題是,運行此行$/ = undef;我的代碼不能正常工作了。其實,我不知道它做了什麼。但如果我忽略了所有評論後可以將其返回,這將會有所幫助。

一般來說,在不更改代碼的其餘部分的情況下忽略所有註釋的有效方法是什麼?

+0

也見http://stackoverflow.com/questions/2578671/where-can-i-find-information-about-perls-special-變量 – 2010-04-14 15:27:15

回答

1

你想使$/地方,如在

$_ = do { local $/; <> }; 

{ 
    local $/; 
    $_ = <>; 
    #... 
} 

或者,你可以使用File::Slurp

2

AWK

$ cat file.c 
one 
two 
three // comment at the back 
// comment in front 
four /* another comment */ 
/* comment spanning 
    multiple 
    lines 
*/ five 
six 
seven 

$ awk -vRS='*/' '{ gsub(/\/\*.*/,"");gsub("//.*","")}1' file.c 
one 
two 
three 


    five 
six 
seven 

awk命令設置記錄分隔RS*/,這對於多線樣式註釋結束標記。因此它會重複記錄,檢查/*(開始標記),然後獲取/*前面的任何內容。這個概念很簡單,你不必爲此製作複雜的正則表達式。類似的,如果你使用Python這樣做,

>>> data=open("file").read() 
>>> for item in data.split("*/"): 
...  if "//" in item: item=item.split("//")[0] 
...  if "/*" in item: item=item.split("/*")[0] 
...  print item 
... 
one 
two 
three 


    five 
six 
seven 
1

如果您正在剝離「嵌套」的意見,即:

/* This is a comment 
/* that has been re-commented */ possibly /* due to */ 
various modifications */ 

正則表達式可能不是最好的解決辦法。特別是如果這樣跨越多行,如上面的例子。

上次我不得不做這樣的事情,我一次只讀一行,保留「/ *」級別(或者特定語言的任何分隔符)並且不打印任何東西除非計數爲0

這是一個例子 - 我提前道歉,因爲這是非常糟糕的Perl,但是,至少這應該給你一個想法:

use strict; 

my $infile = $ARGV[0]; # File name 

# Slurp up input file in an array 
open (FH, "< $infile") or die "Opening: $infile"; 
my @INPUT_ARRAY = <FH>; 
my @ARRAY; 
my ($i,$j); 
my $line; 


# Removes all kind of comments (single-line, multi-line, nested). 
# Further parsing will be carried on the stripped lines (in @ARRAY) but 
# the error messaging routine will reference the original @INPUT_ARRAY 
# so line fragments may contain comments. 
my $commentLevel = 0; 

for ($i=0; $i < @INPUT_ARRAY; $i++) 
{ 
    my @explodedLine = split(//,$INPUT_ARRAY[$i]); 
    my $resultLine =""; 

    for ($j=0; $j < @explodedLine; $j++) 
    { 
     if ($commentLevel > 0) 
     { 
      $resultLine .= " "; 
     } 
     if ($explodedLine[$j] eq "/" && $explodedLine[($j+1)] eq "*") 
     { 
       $commentLevel++; 
       next; 
     }   
     if ($explodedLine[$j] eq "*" && $explodedLine[($j+1)] eq "/") 
     { 
       $commentLevel--; 
       $j++; 
       next; 
     }  
     if (($commentLevel == 0) || ($explodedLine[$j] eq "\n")) 
     { 
      $resultLine .= $explodedLine[$j]; 
     } 
    } 

$ARRAY[$i]=join(" ",$resultLine); 
} 


close(FH) or die "Closing: $!";