use strict; use warnings; use Parse::RecDescent; my $decommendedText = ''; sub concat ($) {$decommendedText .= $_[0]; 1;} my $decomment = <<'GRAMMAR'; file : block(s) block : string {::concat ($item{string}); 1} | m{((?!/\*|"|').)+}s {::concat ($item[-1]); 1} | comment {::concat ($item{comment}); 1;} string : /"([^"]|\\")*"/ {$return = $item[-1] . ($text =~ /^\n/ ? "\n" : ''); 1;} | /'([^']|\\')*'/ {$return = $item[-1] . ($text =~ /^\n/ ? "\n" : ''); 1;} comment : '/*' commentBlock '*/' {$return = $text =~ /^\n/ ? "\n" : ''; 1;} commentBlock : m{((?! \*/ | /\* ).)*}sx comment m{((?! \*/ | /\* ).)*}sx {$return = "\n"; 1;} | m{((?! \*/ | /\* ).)+}sx {$return = ''; 1;} GRAMMAR my $parse = new Parse::RecDescent ($decomment); my $input = <<'DATA'; #include "StdAfx.h" // Tail comment #include "Utility\perftime.h" #pragma hdrstop /* Comment before MACRO */ /* Comment /* and nested comment */ lines */ #define MACRO 10\ + 3 // Multi line macro with comment #define __DEBUG /* comment */ 1 #define STRING 'This is a string' /* comment */ #define COMMENT "/* comment in \"a\" string */" // c++ comment line /* Comment at start for a number of lines */ /* multi-line comment /* nested */ block */ // cpp block char PerfTimer::Buf[64]; DATA $parse->file($input) or die "Parse failed\n"; print $decommendedText;