私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「ソースコードからコメントを抽出しよう」(CodeIQ)を参照してください。
あなたはソースコードからドキュメントを生成するツールの開発を任されており、まず規定の文法で記述されたコメントの内容を抽出するプログラムを作ることにしました。
求められるプログラムの前提条件は、以下の通りとなります。
標準入力から、ASCII文字で構成されたソースコードが送られる
ただしソースコード内の制御文字に関しては、改行コード(LF)のみとする
ソースコードは、1行80文字以下、100行以下とし、改行コード(LF)で行が区切られるものとする
コメントの内容は、"//"から改行コード、あるいは"/*"と"*/"で囲まれた間の文字列を指し、"//" "/*" "*/" 自体は含まれない
"/*"と"*/"で囲まれた間の文字列は複数行、つまり改行コードを含むケースも想定すること
コメント文がネスト(入れ子)、また正しく"/*"から始まっていない、もしくは"*/"で閉じられていないケースは考慮しなくてよい
抽出したコメントの内容を、すべて標準出力に返すこと
以下、入出力例になります。
(引用者注:スペースがわかりにくいので入出力文字列の背景色を薄い灰色にしました)
入力 出力 // C++ sample #include <iostream> C++ sample /* C++ sample */ #include <iostream> // test C++ sample test /* C-Lang sample */ // test #include <stdio.h> C-Lang sample test
ソースコード内のコメントからドキュメントを生成するツールはDoxygenなど有名なものも存在します。
ただ、こうした処理を自前で書けるようになると、SQLにコメントルールを設けたうえで、テーブル設計書を自動生成するといった、既存ツールでは対応できない応用が可能になります。
是非挑戦してみてくださいね。
【問題】
標準入力から、何らかのソースコードが送られます。
このソースコードから、規定のルールで記述されたコメントの内容のみを抽出し、その結果を標準出力に返してください。
Rubyで解答しています。
#!/usr/bin/ruby # main comments = "" multi_line = false while line = gets if line =~ /\/\// then comments += line.chomp[line.index("//")+2..-1] elsif line =~ /\/\*/ && line =~ /\*\// then comments += line[line.index("/*")+2...line.index("*/")] elsif line =~ /\/\*/ then multi_line = true comments += line.chomp[line.index("/*")+2..-1] elsif line =~ /\*\// then comments += line[0...line.index("*/")] multi_line = false elsif multi_line then comments += line end end printf("%s", comments)
特に難しいわけではありません。
ただし、仕様の曖昧さとHTML上でスペースがわかりにくいことにイライラさせられます。
/* Comment1 */ /* Comemnt2 */ #include <stdio.h> int main(void){ printf("Hello World!\n"); /* Hello */ //World }
考え方に書いた通りの実装です。
複数行コメントの場合はmulti_line変数をフラグとして使用しています。
// test /* C-Lang sample */ #include <stdio.h>
test C-Lang sampleわざわざ分けて書いたコメントが1行に出力されてしまいます。使えませんよね。