2012-01-16 8 views
0

私はcppソースファイルをロードしたvar std::string sourceCode;があると仮定します。今では、tr1から含まれているregexクラスのコメントをすべて削除したいと思います(今はMicrosoftコンパイラを使用しているので完全に含まれています)。スペースを使ってコメントを置き換えるのではなく、正しい行数を保持しようとしています。私たちが5行のコメントを削除したとすると、このスペースは5行の改行で埋められ、コードをバックトラックして正しい行番号で計算できるようにします。これまでRegExを使用してC++で複数行のコメントを取り除く

マイコード:

std::regex singleLinedCommentReg("//.*"); 
sourceCode = std::regex_replace(sourceCode, singleLinedCommentReg, std::string("")); 
std::regex multiLinedCommentReg("(/\\*([^*]|[\r\n]|(\\*+([^*/]|[\r\n])))*\\*+/)"); 
std::for_each(
    std::sregex_iterator(sourceCode.begin(), sourceCode.end(), multiLinedCommentReg), 
    std::sregex_iterator(), 
    [&](const std::match_results<std::string::const_iterator>& match) -> bool { 
     // TODO: Replace the current match with an appropriate number of newlines. 
     return true; 
    } 
); 

は誰もが私にその上のいくつかのアドバイスを与えることはできますか?

EDIT#1

私はそれをやってこの種の正規表現を使用する意味があるかどうかの議論についてのコメントを刺激したくないを行います!入力がきれいで、期待どおりであると仮定してください。

+9

それはあなたが思うほど簡単ではありません。ソース 'string s =" not/a/* comment ... "; ' –

+5

あなたの質問に投稿したコードがあなたの正規表現を壊すだろうと考えると、かなり大胆な仮定です。 – Gerald

+1

おそらく、いくつかの翻訳フェーズを実行する必要があります。行の継続は他のほとんどがレクチャーされる前に実行されます:http://codepad.org/LbarZgMg –

答えて

4

あなたのアプローチは正規表現を使用していて、あまりにも複雑です。文脈自由文法と少なくとも同じくらい複雑な状況を解析するために、正規の言語(正規表現)を使用しようとしています。あなたが物事を分割し、C++で処理の一部を行うなら、それは完了しますが、それは乱雑に見えます。

新しい行の文字を失うことなくすべてのコメントを削除する関数を書くことを目標にしている場合は、利用できる多くの解析ツールの1つを使用して解析を生成することをお勧めします。

作成に5分もかからず、機能的に探しています。これをあなたの心臓の内容に変更することができます。これは、フレックス2.5.4でレクサーを生成したり、2.5.35

%{ 
    #include <stdio.h> 
%} 


cbeg "/*" 
cend "*/" 
cppc "//" 
nl "\n"|"\r\n" 

%option noyywrap 
%x mlc 
%% 
{nl}  { fputs(yytext, stdout); } 
{cbeg}  { BEGIN(mlc); } 
{cend}  { fprintf(stderr, "Error: found end of comment without a beginning\n"); return -1; } 
{cppc}.* /* eat up the comment */ 
.  { fputs(yytext, stdout); } 

<mlc>{cend} { BEGIN(INITIAL); } 
<mlc>{cbeg}  { fprintf(stderr, "Error: Found /* inside another /* comment"); return -1; } 
<mlc>.  /* eat up everything else */ 

%% 

int main(int argc, char* argv[]) 
{ 
     yylex(); 
} 

補遺曲がります:上記

が完全に機能するプログラムです。あなたは使った.cを生成できます。

flex -t foo.l > foo.c 

、あなたは

./foo <source.c> source-sans-comments.c 

のようなものが新しいソースファイルを生成します今

cc -o foo foo.c 

を使用して、それをコンパイルすることができます。

0

最高の方法は2つの正規表現を使用することです。 1行目のコメントはすべて削除されます(行番号には影響しません)。その後

、複数行のコメントを除去するための別の正規表現を使用し、それぞれ1以上のループがないよりあるまで:

regex mlc("\\/\\*[^(\\/\\*)]*?\\*\\/"); 

string data = something; 

match_results<std::string::const_iterator> searchresult; 

while (regex_search(data, searchresult, mlc)) { 
    const string& match = searchresult.str(); 

    auto newlinecount = std::count(match.begin(), match.end(), '\n'); 

    data.replace(searchresult.position(), match.length(), newlinecount, '\n'); 
} 
関連する問題