ああ!私はこれが少し上にあることを認めます:
stdinをフィルタリングし、コメントを削除し、関数本体を同じ行に配置するための小さなプログラム。それは、他のものに加えて、クラス宣言内の名前空間と関数定義にだまされます。しかし、それは良いスタートかもしれません:
#include <stdio.h>
#include <assert.h>
int main() {
enum {
NORMAL,
LINE_COMMENT,
MULTI_COMMENT,
IN_STRING,
} state = NORMAL;
unsigned depth = 0;
for(char c=getchar(),prev=0; !feof(stdin); prev=c,c=getchar()) {
switch(state) {
case NORMAL:
if('/'==c && '/'==prev)
state = LINE_COMMENT;
else if('*'==c && '/'==prev)
state = MULTI_COMMENT;
else if('#'==c)
state = LINE_COMMENT;
else if('\"'==c) {
state = IN_STRING;
putchar(c);
} else {
if(('}'==c && !--depth) || (';'==c && !depth)) {
putchar(c);
putchar('\n');
} else {
if('{'==c)
depth++;
else if('/'==prev && NORMAL==state)
putchar(prev);
else if('\t'==c)
c = ' ';
if(' '==c && ' '!=prev)
putchar(c);
else if(' '<c && '/'!=c)
putchar(c);
}
}
break;
case LINE_COMMENT:
if(' '>c)
state = NORMAL;
break;
case MULTI_COMMENT:
if('/'==c && '*'==prev) {
c = '\0';
state = NORMAL;
}
break;
case IN_STRING:
if('\"'==c && '\\'!=prev)
state = NORMAL;
putchar(c);
break;
default:
assert(!"bug");
}
}
putchar('\n');
return 0;
}
そのc++なので、ファイルに入れて、「stripper」という名前のファイルにコンパイルしてから、次のようにします。
cat my_source.cpp | ./stripper | grep JOHN_DOE
したがって、入力を検討してください。
int foo ( int arg1 )
{
/// code
}
void bar ( std::string arg2 )
{
/// code
aFunctionCall( JOHN_DOE );
/// more code
}
""の出力cat example.cpp | ./stripper
は次のとおりです。
int foo ( int arg1 ) { }
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
""の出力cat example.cpp | ./stripper | grep JOHN_DOE
は次のとおりです。
void bar ( std::string arg2 ){ aFunctionCall( JOHN_DOE ); }
関数名を見つける作業(「(
」の前にある最後の識別子を推測する)は、読者の練習問題として残されています。