Arggh!
stdin、stripコメント、およびput関数本体を同じ行にフィルターする小さなプログラムです。それは他のもののほかに、クラス宣言内の名前空間と関数定義にだまされるでしょう。しかし、それは良いスタートかもしれません。そして、そうちょうどそれファイルで、そのCの++
#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;
}
「ストリッパー」という名前のファイルにそれをコンパイルし、そして:
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); }
(「(
」を前に置くために、その最後の識別子を推測)関数名を見つけるのジョブは、読者への課題として残されています。
関数名はどこから来たのですか? –
はい、上記のコードから来るはずですが、grepコマンドで関数の名前を取得できませんでした。 –