私は C++ プロジェクトの行カウンターについて調査を行っていましたが、それらが使用するアルゴリズムに非常に興味があります。そのようなアルゴリズムの実装をどこで見ることができるか知っている人はいますか?
4 に答える
コードカウンターの無料のオープンソースソース行であるclocがあります。C++を含む多くの言語をサポートしています。私は個人的にそれを使用して、プロジェクトの行数を取得しています。
そのsourceforgeページで、ダウンロード用のperlソースコードを見つけることができます。
行カウンターとは、行を数えるプログラムを意味する場合、アルゴリズムは非常に簡単'\n'
です。コード内の数を数えるだけです。一方、C++ ステートメントをカウントしたり、他のメトリクスを生成したりするプログラムを意味する場合... 100% 正確ではありませんが、'}' と ';' をカウントするだけで、過去にかなり良い結果が得られました。(もちろん、コメントや文字列リテラル、文字リテラルは無視します)。より正確にするには、おそらく実際の C++ を解析する必要があります。
行番号をカウントするために実際にコードを解析する必要はありません。トークン化するだけで十分です。
アルゴリズムは次のようになります。
int lastLine = -1;
int lines = 0;
for each token {
if (isCode(token) && lastLine != token.line) {
++lines;
lastLine = token.line;
}
}
トークン化中に収集する必要がある唯一の情報は次のとおりです。
- それがどのタイプのトークンであるか (演算子、識別子、コメントなど) 「非コード トークン」(コメント) と「コードトークン」(その他)
- トークンが発生するファイルの行。
トークン化の方法については、あなたが理解する必要がありますが、このような単純なケースのトークン化を手書きすることは難しくありません。使用できますflex
が、おそらく冗長です。
編集
「トークン化」について言及しましたが、簡単に説明しましょう。
トークン化は、コンパイルの最初の段階です。トークン化の入力はテキスト (複数行のプログラム) であり、出力は次のような「トークン」のシーケンスです: 何らかの意味を持つシンボル。たとえば、次のプログラムです。
#include "something.h"
/*
This is my program.
It is quite useless.
*/
int main() {
return something(2+3); // this is equal to 5
}
次のようになります。
PreprocessorDirective("include")
StringLiteral("something.h")
PreprocessorDirectiveEnd
MultiLineComment(...)
Keyword(INT)
Identifier("main")
Symbol(LeftParen)
Symbol(RightParen)
Symbol(LeftBrace)
Keyword(RETURN)
Identifier("something")
Symbol(LeftParen)
NumericLiteral(2)
Operator(PLUS)
NumericLiteral(3)
Symbol(RightParen)
Symbol(Semicolon)
SingleLineComment(" this is equal to 5")
Symbol(RightBrace)
など。
トークンは、そのタイプに応じて、任意のメタデータが添付されている場合があります (つまり、シンボル タイプ、演算子タイプ、識別子テキスト、またはトークンが見つかった行の番号など)。
このようなトークンのストリームはパーサーに供給され、パーサーはこれらのトークンに関して記述された文法生成規則を使用して、たとえば構文ツリーを構築します。
コードの完全な構文ツリーを提供する完全なパーサーを実行することは困難であり、それが C++ の場合は特に困難です。ただし、トークン化 (または「字句解析」または「字句解析」) の方が簡単です。あまり詳細を気にしない場合は、有限状態マシンを使用してトークナイザーを自分で作成できるはずです。
実際に出力を使用してコード行 (つまり、少なくとも「コード」トークン、つまりコメント以外の任意のトークンが開始する行) をカウントする方法については、前に説明したアルゴリズムを参照してください。
人々があなたの問題を理解するのに非常に苦労している理由の一部は、「C ++の行数を数える」自体がアルゴリズムであるためだと思います。おそらく、あなたが尋ねようとしているのは、「ファイル内の c++ の行を特定するにはどうすればよいですか?」ということです。これはまったく別の質問であり、コスは説明しようとしてかなりうまくやっているようです.