(57)【要約】【課題】従来の複雑さを算出する方法では、分岐や繰返しの個数によって各関数がどの程度複雑かは判断できたものの、いくつもの構造が入れ子になり、処理の流れを読み解くことが難しい状態のプログラムの有無を指標から読み取ることはできないという問題があった。【解決手段】本発明にかかるメトリクス算出装置は、ソースプログラム１を解析して構文木を構築し、構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部である構文解析部２、指標値算出部３と、構文木内において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値をメトリクスに反映させる第１反映部である累積指標値算出部４とを備える。【選択図】図１
2011257965.tif 000002
【特許請求の範囲】
【請求項１】
ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、
前記構文木内において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値を前記メトリクスに反映させる第１反映部とを備える、
メトリクス算出装置。
【請求項２】
前記構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、前記メトリクスに反映させる第２反映部をさらに備える、
請求項１に記載のメトリクス算出装置。
【請求項３】
ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、
前記構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、前記メトリクスに反映させる反映部とを備える、
メトリクス算出装置。
【請求項４】
前記算出部は、前記構文木内の一部の分岐命令文数および繰返命令文数を積算して、前記プログラムの部分メトリクスを算出することが可能であり、
前記第１反映部は、前記構文木内の前記一部において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値を前記部分メトリクスに反映させる、
請求項１または２に記載のメトリクス算出装置。
【請求項５】
前記算出部は、前記構文木内の一部の分岐命令文数および繰返命令文数を積算して、前記プログラムの部分メトリクスを算出することが可能であり、
前記反映部または前記第２反映部は、前記構文木内の前記一部に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数を、前記部分メトリクスに反映させる、
請求項２または３に記載のメトリクス算出装置。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウエアの開発支援技術のうちの一つで、例えば、プログラムのレビューや品質管理にソフトウエアの状態を表す指標値であるメトリクスを算出する技術に関する。
【背景技術】
【０００２】
近年、ソフトウエアの規模が拡大し、既存のプログラム資産の再利用と各プログラムの品質向上が重要となっている。プログラム資産を再利用する際に、プログラムの複雑度や結合度など様々な指標値（メトリクス）を用いて、再利用の容易さの検討や修正すべき箇所の洗い出しを行うことが、よく行われている。
【０００３】
例えば、関数コール数や最大ネスト数を求める方法が、特許文献１に述べられている。また、条件分岐命令の数や繰返命令の数を用いて複雑性を示す指標を算出することは広く行われており、例えば、マッケーブのサイクロマティック複雑度と呼ばれるものが有名である（特許文献２参照）。また、関数毎のメトリクスとして、プログラムおよびその中の関数の複雑度等であるメトリクスを求めることが特許文献１に述べられている。
【０００４】
また、プログラムのボトルネックになりやすい箇所を解析する方法として、条件分岐命令や繰返命令の段数を用いてメトリクスを算出する方法が特許文献３に述べられている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２００６−１１３９３４号公報（図３、１４、１５）
【特許文献２】特開２００７−２１９６４３号公報（第２段落）
【特許文献３】特開２００７−１７９４８８号公報（図１７、１８）
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかし、特許文献１、２、３に述べられている従来の複雑さを算出する方法では、分岐や繰返しの個数によって各関数がどの程度複雑かは判断できたものの、いくつもの構造が入れ子になり、処理の流れを読み解くことが難しい状態のプログラムの有無を指標から読み取ることはできなかった。例えば、繰返文の処理の中でさらに繰返文が実行される場合や、ｉｆ文の中にｉｆ文があり、さらにその中にｉｆ文があるような場合は、どこまでが処理の終わりかを判断しながら構造を読まなければならず、理解することが難しい。しかし、従来の複雑さ（メトリクス）を算出する方法では、単に繰返文が５回順に出てくる場合と、繰返文の処理の中でさらに繰返文が呼ばれるという入れ子構造が５段になっている場合とでは、同じ値の複雑さ（メトリクス）として扱われていて、区別がつかないという問題があった。
【０００７】
本発明は、上記のような問題を解決するためになされたものであり、いくつもの構造が入れ子になったような複雑なプログラムであっても、その構造に応じて適切にそのプログラムのメトリクスを算出可能な装置の提供を目的とする。
【課題を解決するための手段】
【０００８】
本発明にかかる第１のメトリクス算出装置は、ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、前記構文木内において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値を前記メトリクスに反映させる第１反映部とを備える。
【０００９】
また、本発明にかかる第２のメトリクス算出装置は、ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、前記構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、前記メトリクスに反映させる反映部とを備える。
【発明の効果】
【００１０】
本発明にかかる第１のメトリクス算出装置によれば、ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、前記構文木内において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値を前記メトリクスに反映させる第１反映部とを備えることにより、構文木の構造（入れ子）を考慮した、プログラムのメトリクスを算出することが可能となる。
【００１１】
また、本発明にかかる第２のメトリクス算出装置によれば、ソースプログラムを解析して構文木を構築し、前記構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部と、前記構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、前記メトリクスに反映させる反映部とを備えることにより、構文木中に呼び出される関数を考慮した、プログラムのメトリクスを算出することが可能となる。
【図面の簡単な説明】
【００１２】
【図１】実施の形態１の構成図である。
【図２】実施の形態１のハードウエア構成図である。
【図３】実施の形態１のソースプログラム例を示す図である。
【図４】実施の形態１の構文木例を示す図である。
【図５】実施の形態１の構文木のノードのデータ構造を示す図である。
【図６】実施の形態１の指標値算出部の動作を示すフローチャートである。
【図７】実施の形態１の指標値算出部の一部である、サブノード指標値算出処理のフローチャートである。
【図８】実施の形態１の累積指標値算出処理のフローチャートである。
【図９】実施の形態１の累積指標値算出処理の一部である、条件分岐文累積指標値算出処理のフローチャートである。
【図１０】実施の形態１の累積指標値算出処理の一部である、繰返文累積指標値算出処理のフローチャートである。
【図１１】実施の形態１の累積指標値算出処理の一部である、関数累積指標値算出部のフローチャートである。
【図１２】実施の形態２の構成図である。
【図１３】実施の形態２の部分指標算出部の動作を示すフローチャートである。
【図１４】実施の形態２の部分指標算出部の一部である、行情報出力付きサブノード指標値算出処理のフローチャートである。
【図１５】実施の形態２の部分指標算出部の一部である、行情報出力付きサブノード指標値算出処理のフローチャートである。
【図１６】実施の形態２の部分指標値記憶部のデータ構造を示す図である。
【図１７】実施の形態２の部分指標値提示部が作成する画面例を示す図である。
【図１８】実施の形態２の部分指標値記憶部のデータ構造（差分記憶の場合）を示す図である。
【発明を実施するための形態】
【００１３】
＜Ａ．実施の形態１＞
＜Ａ−１．構成＞
図１に本実施の形態１に係る本発明の全体構成を示す。本発明にかかるメトリクス算出および提示装置は、ソースプログラム１を読み込む構文解析部２と、関数累積指標値算出部５と、関数累積指標値算出部５と接続される累積指標値算出部４と、構文解析部２の出力と累積指標値算出部４の出力とを用いて、算出結果６を出力する指標値算出部３とを備える。
【００１４】
構文解析部２は、ソースプログラム１を読み込み、解析して構文木を作成する。指標値算出部３は、構文解析部２が作成した構文木を読み込み、また累積指標値算出部４と関数累積指標値算出部５とを用いて累積指標値を算出し、その結果を考慮して、構文木内の分岐命令文数および繰返命令文数を積算した指標値（メトリクス）を算出し、算出結果６として出力する。構文解析部２と指標値算出部３とは、メトリクスを算出する算出部として機能する。
【００１５】
図２に本発明のハードウエア構成を示す。相互に接続される、中央演算装置８、ＲＡＭなどの主記憶装置９、ハードディスクドライブなどの記憶装置１０を搭載した、ＰＣ（パーソナルコンピュータ）などの計算機７と、計算機７と接続されるマウス、キーボードなどの入力装置１１と、計算機７と接続される液晶ディスプレイなどの表示装置１２とを備える。図１中の構文解析部２、指標値算出部３、累積指標値算出部４、ソースプログラム１は、図２における記憶装置１０に保存され、中央演算装置８で処理を行う際に主記憶装置９に展開される。
【００１６】
＜Ａ−２．動作＞
図１の構文解析部２は、従来技術のたとえばＣ言語やＣ＋＋言語を解析するものと同じものである。ソースプログラム１を先頭から読み込んで構文解析を行い、構文木を作成する。例えば、図３に例として示すようなソースプログラムを読み込み、図４の構文木を作成することができる。ここで図４の構文木は、図３のソースプログラムのうち関数ｆｕｎｃ１の部分だけを例として表したものである。また図５に、この構文木中の各ノードの構造を示す。ノードは例えば、ノードの種類、ノードの値（プログラム中の文字列。例えば、変数名、関数名等）、およびそのノードがソースプログラム中の何行目にあるかを示す行数を格納するものである。
【００１７】
図６は、図１に示す指標値算出部３の処理フローである。まず、図１に示す構文解析部２から受け取った構文木中の開始ノードをｎとする（ステップＳＴ６０１）。次に、ノードｎに対して、関数累積指標値算出部５、累積指標値算出部４からの出力を考慮して、サブノード指標値算出処理を行う（ステップＳＴ６０２）。このとき、条件分岐文累積数、繰返文累積数はそれぞれ０として、ステップＳＴ６０２を開始する。ステップＳＴ６０２の算出結果を変数（ｖａｌｕｅ）に代入し（ステップＳＴ６０３）、算出結果６を出力して指標値算出部３における処理を終了する。
【００１８】
図７は、図６中のステップＳＴ６０２で行う、サブノード指標値算出処理の処理フローである。まず、このサブノード指標値算出処理を開始する際に与えられた条件分岐文累積数を変数（ｉｆｃｏｕｎｔ）に、繰返文累積数を変数（ｌｏｏｐｃｏｕｎｔ）にそれぞれ代入する（ステップＳＴ７０１）。
【００１９】
そして、構文木の中のサブノードを、その深さを優先して辿る。ここでは、ノードｎの中のサブノードを前から順に検索し、まだ処理していないサブノードをサブノードｎｎとする（ステップＳＴ７０２）。そして、本処理の算出結果を出力するための変数（ｓｕｂｖａｌｕｅ）の値を０で初期化する（ステップＳＴ７０３）。
【００２０】
次に、ノードｎ中にサブノードｎｎが存在するかどうか、すなわちノードｎ中でサブノードを探した結果、まだ未処理のものが存在するかどうかを判断する（ステップＳＴ７０４）。
【００２１】
その結果、サブノードｎｎが存在するようであれば、そのサブノードｎｎに対してサブノード累積指標値算出処理を行い（ステップＳＴ７０５）、その出力値を変数（ｓｕｂｖａｌｕｅ）に加算する（ステップＳＴ７０６）。次に、そのサブノードｎｎにさらなるサブノードがあった場合に、それらの複雑性をも加算する。具体的にはサブノードｎｎに対して、再帰的にサブノード指標値算出処理を行い（ステップＳＴ７０７）、その結果を変数（ｓｕｂｖａｌｕｅ）に加算する（ステップＳＴ７０８）。そして、与えられたノードｎ中の次の未処理のサブノードを探してｎｎとし（ステップＳＴ７０９）、再びステップＳＴ７０４から処理を行う。
【００２２】
こうして何回か処理を繰返して、ステップＳＴ７０４で次の未処理のサブノードｎｎがなくなった、すなわち全てのサブノードに対して処理が終了した場合、変数（ｓｕｂｖａｌｕｅ）を算出結果として出力し（ステップＳＴ７１０）、処理を終了する。
【００２３】
ここで、本実施の形態１では、ステップＳＴ７０７およびステップＳＴ７０８の処理をサブノードｎｎがなくなるまで続けることとしているが、例えば最初に与えられたノードｎから３階層ないしは５階層まで呼び、例えば５階層まで呼ぶ場合には６階層以上はサブノードの値を算出しない、として実現してもよい。これには、最初のサブノードから現在何階層目の処理を行っているかの変数を用意し、一階層下がるたびに１増やしていき、その数が閾値を越えたときにはそのさらなるサブノードに対してはステップＳＴ７０７の処理を再帰的に行わないとすればよい。このようにして実現すると、膨大なソースコードで関数呼び出しが何階層にもなっている場合に、あるソースプログラムの関数から直接あるいは２、３階層分の部分だけの複雑さを算出することができるというメリットがある。
【００２４】
図８は、図７中のステップＳＴ７０５で行われる、サブノード累積指標値算出処理の処理フローである。すなわちこれが、図１中の第１反映部としての累積指標値算出部４における処理である。
【００２５】
まず、与えられたサブノードｎｎの種類によって振り分ける（ステップＳＴ８０１）。具体的には、サブノードｎｎが条件分岐のサブノードであった場合、すなわち、ｉｆ文のｉｆノード、ｃａｓｅ文のｃａｓｅノード、ｇｏｔｏ文のｇｏｔｏノードのいずれかであった場合、そのサブノードｎｎに対して条件分岐文累積指標値算出処理を実施する（ステップＳＴ８０２）。また、サブノードｎｎが繰返文のサブノードであった場合、すなわち、ｆｏｒ文のｆｏｒノード、ｗｈｉｌｅ文のｗｈｉｌｅノード、ｄｏ〜ｗｈｉｌｅ文のｄｏノードのいずれかであった場合、そのサブノードｎｎに対して繰返文累積指標値算出処理を実施する（ステップＳＴ８０３）。また、サブノードｎｎが関数呼び出しのサブノードであった場合、そのサブノードｎｎに対して関数累積指標値算出処理を行う（ステップＳＴ８０４）。サブノードｎｎがこれまでに述べたいずれにも該当しないサブノードであった場合は、そのサブノードｎｎについては後述の算出結果を０とする（ステップＳＴ８０５）。ステップＳＴ８０２〜８０５までの処理の結果は、算出結果として出力される（ステップＳＴ８０６）。
【００２６】
図９は、図８中のステップＳＴ８０２で行われる、条件分岐文累積指標値算出処理の処理フローである。まず、与えられたサブノードをサブノードｎｎとし、この処理内部で用いる変数（ｃｏｕｎｔ）と変数（ｓｕｍ）とを０で初期化する（ステップＳＴ９０１）。そして、事前準備として、変数（ｃｏｕｎｔ）が変数（ｉｆｃｏｕｎｔ）の値になるまで、
ｃｏｕｎｔ  ：＝  ｃｏｕｎｔ＋１（ｃｏｕｎｔに、ｃｏｕｎｔ＋１の値を代入する）と、
ｓｕｍ  ：＝  ｓｕｍ  ＋  ｃｏｕｎｔ（ｓｕｍに、ｓｕｍ  ＋  ｃｏｕｎｔの値を代入する）との処理を繰返す（ステップＳＴ９０２）。
【００２７】
これらの式は、ノードｎのｉｆｃｏｕｎｔ個目の累積数（重畳数）による重みを算出している。この例では、累積数による重みを、累積数の増加につれて１、３、６、１０と増えるように計算式で求めている。
【００２８】
次に、サブノードｎｎが条件分岐文、すなわちｉｆノード、ｃａｓｅノード、ｇｏｔｏノードのいずれかであるかどうかを調べ（ステップＳＴ９０３）、もしそうであれば、ｃｏｕｎｔ  ：＝  ｃｏｕｎｔ＋１と、ｓｕｍ  ：＝  ｓｕｍ  ＋  ｃｏｕｎｔとを１回ずつ行う（ステップＳＴ９０４）。すなわち、分岐命令文内にさらに分岐命令文が含まれる場合に、その重畳数に応じた値をメトリクスに反映させている。
【００２９】
次に、サブノードｎｎとノードｎとが同一ノードであるかどうか調べ（ステップＳＴ９０５）、同一ノードでなければ、サブノードｎｎの親ノードをｎｎとして（ステップＳＴ９０６）ステップＳＴ９０３からの処理を繰返す。一方、ステップＳＴ９０５の結果、サブノードｎｎとノードｎとが同一ノードであれば、最上位のノードｎまで累積数を計算したことになるので、変数（ｓｕｍ）の値を本処理の算出結果として出力し（ステップＳＴ９０７）、本処理を終了する。
【００３０】
累積数による重みの計算の仕方は、この例では、ｃｏｕｎｔ  ：＝  ｃｏｕｎｔ＋１と、ｓｕｍ  ：＝  ｓｕｍ  ＋  ｃｏｕｎｔとの式により求めたが、累積数が増えるとそれにつれて増えるような算出方法であればよく、そのような算出方法であれば同様の効果がある。また、計算式を用いて算出したが、累積数とその重みを表にして予め記憶しておいて、その表を参照する方法でもよく、そのような場合でも同様の効果がある。
【００３１】
また、本実施の形態１では、最上位のノードｎまで辿って算出を行ったが、４段程度の関数呼び出しを発見して終了するものでもよい。すなわち、関数呼び出しのサブノードを何階層辿ったかを初期値０の変数で記憶しておき、１回関数呼び出しのサブノードが出現するごとにこの変数値を１増やし、ステップＳＴ９０５では、サブノードｎｎが最上位のノードｎと同じであるかを比較する方法によるのではなく、関数呼び出しが出現した回数が一定数、例えば４段まで辿るのであれば、４より小さいかどうかを比較する方法をとる。このような方法をとれば、膨大なソースコードで関数呼び出しが何階層にもなっている場合に、あるソースプログラムの関数から直接あるいは２、３階層分の部分だけの複雑さを算出することができるというメリットがある。
【００３２】
図１０は、図８中のステップＳＴ８０３で行われる、繰返文累積指標値算出処理の処理フローである。図９の条件分岐文累積指標値算出処理の処理フローとほぼ同様の処理（ステップＳＴ９０１、ステップＳＴ９０４〜９０７）であるが、ステップＳＴ１００２で、変数（ｃｏｕｎｔ）が変数（ｌｏｏｐｃｏｕｎｔ）の値になるまで、ｃｏｕｎｔ  ：＝  ｃｏｕｎｔ＋１と、ｓｕｍ  ：＝  ｓｕｍ  ＋  ｃｏｕｎｔとの処理を繰り返し、ステップＳＴ１００３で、サブノードｎｎが繰返文、すなわちｗｈｉｌｅ文のｗｈｉｌｅノード、ｆｏｒ文のｆｏｒノード、ｄｏ〜ｗｈｉｌｅ文のｄｏノードのいずれかであるかどうかを調べる処理を行うことが、条件分岐文累積指標値算出処理の場合とは異なる。すなわち、繰返命令文内にさらに繰返命令文が含まれる場合に、その重畳数に応じた値をメトリクスに反映させている。
【００３３】
図９および図１０では、ステップＳＴ９０３およびステップＳＴ１００３で、ｉｆノード、ｃａｓｅノード、ｇｏｔｏノード、および、ｗｈｉｌｅノード、ｆｏｒノード、ｄｏノードのように、Ｃ言語あるいはＣ＋＋言語の場合の処理について説明したが、他の手続き型言語や、構造化された手続き型視覚的言語でも、条件文および繰返文に相当するノードについて同等の処理を行えばよく、その場合には同等の効果がある。
【００３４】
図１１は、図８中のステップＳＴ８０４の関数累積指標値算出処理、すなわち図１中の反映部および第２反映部としての関数累積指標値算出部５の処理フローである。まず、本処理の呼び出し時に関数呼び出しのサブノードが与えられ、そのサブノードに対応する実際の処理、すなわち、呼び出し先関数の最上位ノードをサブノードｎｎとする（ステップＳＴ１１０１）。次に、この処理を呼び出す際に与えられた条件分岐文累積数の値を変数（ｉｆｃｏｕｎｔ）に、繰返文累積数の値を変数（ｌｏｏｐｃｏｕｎｔ）にそれぞれ代入する（ステップＳＴ１１０２）。そして、サブノードｎｎに対してサブノード指標値算出処理を行う（ステップＳＴ１１０３）。このサブノード指標値算出処理は図７に示した処理と同様の処理であり、この処理により、関数に含まれる分岐命令文数および繰返命令文数に応じた値を、メトリクスに反映させる。そして、ステップＳＴ１１０３の算出結果を出力して（ステップＳＴ１１０４）、関数累積指標値算出処理を終了する。
【００３５】
図１１のステップＳＴ１１０１で、与えられた関数呼び出しのサブノードから対応する呼び出し先関数を一つ選んだが、例えば、その関数がＣ＋＋言語の仮想関数の場合、実際に呼ばれる関数は主体となるオブジェクトの型によって決まることになり、動的解析時には一意に特定できるものの、静的解析時には決めることはできない。このような場合、呼び出しうる全ての関数に対してそれぞれ指標値を算出し、その最大値を算出結果とする、あるいは、その平均値を算出結果とする、などの方法で指標値（メトリクス）を算出する。
【００３６】
本実施の形態１では、発見したサブノードに対して、個々に親ノードを辿って累積数を算出したが、累積数、段数、指標値それぞれ変数としサブノードをその深さを優先して探索しながら、そのサブノードを一段深く探索するときに累積数と段数とを追加し、一段サブノードを戻るときにこの値を戻す、また、指標値については順次値を追加していく、という方法で実現することもでき、そのようにした場合でも同様の効果がある。
【００３７】
＜Ａ−３．効果＞
本発明にかかる実施の形態１によれば、メトリクス算出装置において、ソースプログラム１を解析して構文木を構築し、構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部である構文解析部２、指標値算出部３と、構文木内において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値をメトリクスに反映させる第１反映部である累積指標値算出部４とを備えることで、構文木の構造（入れ子）を考慮した、プログラムのメトリクスを算出することが可能となる。
【００３８】
具体的には、入れ子構造の中で複数分岐命令、繰返命令が含まれる場合、（入れ子構造とならずに）単に同種の命令が順に含まれる場合に比べて大きい値の指標値（メトリクス）を出力するようになる。しかも、入れ子構造の段数が増えるほど出力する指標値も累進的に大きくなるため、入れ子構造が深く複雑になっている部分がプログラム中のどこにあるかについて、指標値を見るだけで把握することが可能となる。
【００３９】
さらに、本発明では、単に入れ子構造の大きさ自体を指標値に反映させるのではなく、入れ子構造の中で同種の命令が呼ばれる段数を指標値に反映させることで、同種類の命令が多段に実行されている事例について、指標値を大きくすることで発見することを可能とする。これにより、性能の出ないプログラムでしばしば見られる、本来何重にも繰返す必要のない同種類の入れ子構造（特に、多段の繰返文）からなるプログラムを発見しやすくしている。
【００４０】
また、本発明にかかる実施の形態１によれば、メトリクス算出装置において、構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、メトリクスに反映させる第２反映部である関数累積指標値算出部５をさらに備えることで、構文木中に呼び出される関数を考慮した、プログラムのメトリクスを算出することが可能となる。
【００４１】
また、本発明にかかる実施の形態１によれば、メトリクス算出装置において、ソースプログラム１を解析して構文木を構築し、構文木内の分岐命令文数および繰返命令文数を積算して、プログラムのメトリクスを算出する算出部である構文解析部２、指標値算出部３と、構文木内に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数に応じた値を、メトリクスに反映させる反映部である関数累積指標値算出部５とを備えることで、構文木中に呼び出される関数を考慮した、プログラムのメトリクスを算出することが可能となる。
【００４２】
＜Ｂ．実施の形態２＞
従来、複雑度や結合度等の指標値（メトリクス）は、プログラムのファイル単位、あるいは関数単位で提示されていた。指標値（メトリクス）が標準値に収まらない関数が、必ずしも悪い処理であるとは限らないため、その判断のためには手動での選別が必要であった。長い関数等の場合、本当に問題があるのか、問題がある場合でもどの部分が問題なのかは、指標値からだけではわからず、テキストエディタなどを用いて関数の中身を順に確認する必要があった。本実施の形態２では、このような問題を解決するメトリクス算出装置を示す。
【００４３】
＜Ｂ−１．構成＞
図１２は、実施の形態２に係る本発明を示す構成図である。本実施の形態２では、本発明にかかるメトリクス算出装置は、ソースプログラム１を読み込む構文解析部２と、関数累積指標値算出部５と、関数累積指標値算出部５と接続される累積指標値算出部４と、構文解析部２の出力である構文木と累積指標値算出部４の出力とを用いて、ソースプログラム１中のある部分の指標値（部分メトリクス）を算出する部分指標値算出部１３と、その算出した部分ごとの指標値を記憶する部分指標値記憶部１４と、部分指標値記憶部１４の値を利用して表示装置１２に部分指標値を表示する部分指標値提示部１５とを備える。
【００４４】
本実施の形態２では、ソースプログラム１のある部分として、行ごとの情報を出力するものとする。構文解析部２、累積指標値算出部４、関数累積指標値算出部５は、実施の形態１と同じものである。また本実施の形態２のハードウエア構成は図２と同様である。
【００４５】
図１２中の構文解析部２、部分指標値算出部１３、累積指標値算出部４、ソースプログラム１、部分指標値記憶部１４、および、部分指標値提示部１５は、図２における記憶装置１０に保存され、中央演算装置８で処理を行う際に主記憶装置９に展開される。
【００４６】
＜Ｂ−２．動作＞
図１３に、部分指標値算出部１３の処理フローを示す。まず、処理で用いる行数用の変数（ｌｉｎｅ）を１で、最大値用の変数（ｍａｘ）を０で初期化し、直前に処理したノードを記憶しておく変数（ｐｎ）をＮＵＬＬで初期化する（ステップＳＴ１３０１）。これらの変数は大域変数として用意し、後述のステップＳＴ１３０３から呼ばれる処理や、さらにその中で呼ばれる処理をまたいで利用する。
【００４７】
次に、構文解析部２から受け取った構文木中の開始ノードをｎとする（ステップＳＴ１３０２）。次に、ノードｎに対して、関数累積指標値算出部５、累積指標値算出部４に基づいて、行情報出力付きサブノード指標値算出処理を行う（ステップＳＴ１３０３）。このとき、条件分岐文累積数、繰返文累積数はそれぞれ０として、ステップＳＴ１３０３を開始する。そして、ステップＳＴ１３０３での値を算出結果として出力し（ステップＳＴ１３０４）、処理を終了する。
【００４８】
図１４、図１５は、図１３中のステップＳＴ１３０３の行情報出力付きサブノード指標値算出処理の処理フローである。まず、与えられた条件分岐文累積数の値を変数（ｉｆｃｏｕｎｔ）に、繰返文累積数の値を変数（ｌｏｏｐｃｏｕｎｔ）にそれぞれ代入する（ステップＳＴ１４０１）。
【００４９】
そして、与えられたノードｎのサブノードのうち、未処理のサブノードをｎｎとする（ステップＳＴ１４０２）。これは、サブノードのリストのうち、前から順に処理を行うとする。そして、算出結果用の変数（ｓｕｂｖａｌｕｅ）を０で初期化する（ステップＳＴ１４０３）。
【００５０】
次に、ノードｎ中に処理すべきサブノードｎｎがまだ残っているかどうかを判断する（ステップＳＴ１４０４）。その結果、もしサブノードｎｎあれば、そのサブノードｎｎの行数が変数（ｌｉｎｅ）よりも大きいかどうか比較する（ステップＳＴ１４０５）。もし、大きくなければ、すなわち、前回処理したサブノードとこのサブノードとがソースプログラム１中の同じ行に書かれていたのであれば、変数（ｐｎ）にｎｎを代入し（ステップＳＴ１４０６）、サブノードｎｎに対して累積指標値算出処理を行う（ステップＳＴ１４０７）。この累積指標値算出処理は図８に示した処理と同様の処理である。
【００５１】
そして、その算出結果を変数（ｖ）に代入する（ステップＳＴ１４０８）。変数（ｖ）の値が変数（ｍａｘ）の値より大きいかを調べ（ステップＳＴ１４０９）、もし大きければ、変数（ｍａｘ）に変数（ｖ）の値を代入する（ステップＳＴ１４１０）。そして、変数（ｓｕｂｖａｌｕｅ）に変数（ｖ）の値を加算する（ステップＳＴ１４１１）。次に、サブノードｎｎに対する行情報出力付きサブノード指標値算出処理を、再帰的に呼び出す（ステップＳＴ１４１２）。そして、変数（ｓｕｂｖａｌｕｅ）に算出結果の値を加算し（ステップＳＴ１４１３）、与えられたノードのうちの未処理のサブノードをｎｎとして（ステップＳＴ１４１４）、ステップＳＴ１４０４に戻る。
【００５２】
これを繰返していくうちに、ステップＳＴ１４０５でサブノードｎｎの行数が、変数（ｌｉｎｅ）よりも大きくなった場合（再帰呼び出し中を含む）、サブノードｐｎがｌｉｎｅ行の最後のサブノードであり、行情報である行数とその行内最大の指標値（ｍａｘ）を部分指標値記憶部１４に出力し（ステップＳＴ１４１５）、変数（ｍａｘ）の値を０とする（ステップＳＴ１４１６）。そして、ステップＳＴ１４０６から処理を続ける。
【００５３】
また、この処理を繰返し、ステップＳＴ１４０４で未処理のサブノードｎｎがなくなった場合、行数とその行内最大の指標値（ｍａｘ）を出力し（ステップＳＴ１４１７）、変数（ｓｕｂｖａｌｕｅ）の値を算出結果として出力して（ステップＳＴ１４１８）、この処理を終わる。
【００５４】
ここで、ステップＳＴ１４１２およびステップＳＴ１４１３の処理を、本実施の形態２では子ノードがなくなるまで続けることとしているが、実施の形態１のステップＳＴ７０７とステップＳＴ７０８の処理の場合と同様に、例えば最初に与えられたノードから３階層ないしは５階層まで呼び、例えば５階層までとした場合には６階層以上は子ノードの値を算出しない、として実現してもよい。
【００５５】
部分指標値記憶部１４における記憶内容の例を図１６に示す。これはソースプログラム１として図３に示すものを入力して、本実施の形態２の処理を実行した後の値が入ったものを、ｆｕｎｃ１とｆｕｎｃ２について示したものである。本実施の形態２では、部分指標値記憶部１４は、関数ごとに表を新たに作成して開始行と終了行を記憶し、また行数とその指標値を関数毎に記憶するものとする。例えば図３のソースプログラム１では、２行目から１３行目までがｆｕｎｃ１である。その間の各行の指標値のうち最大のものが、指標値のところに記載される。ｆｕｎｃ２についても同様である。
【００５６】
図１７に、部分指標値提示部１５が部分指標値記憶部１４の情報をもとに表示装置１２に出力するグラフの例を示す。図において、縦軸がソースプログラム１の行数、横軸が行ごとに算出した指標値となっている。この例では棒グラフとして表示したが、折れ線グラフなどのグラフを用いて表示してもよい。このように、行ごとの指標値をグラフの形で表示することで、長い関数でもどの部分が複雑になっているのかが容易に判断できるようになる。
【００５７】
本実施の形態２では、部分指標値記憶部１４が部分指標値（部分メトリクス）を記憶するのに、各行ごとの指標値を記憶したが、たとえば指標値が変化する箇所だけ記憶しても良い。例えば、図１８は、図１６のｆｕｎｃ１に関する表を、指標値が変化する行数とその値を記憶したものである。これを実現するには、図１４中、ステップＳＴ１４１５とステップＳＴ１４１７で、書き込もうとした指標値が最後に書き込んだ指標値と異なる場合だけ書き込めばよい。この手法によれば、毎行ごとに記憶しなくてよいため部分指標値記憶部１４に必要な記憶容量が少なくてすむ、折れ線グラフや棒グラフで部分指標値記憶部１４の値を表現しようとする際に、値が変化する行を探す必要なく描画できる、といった効果がある。
【００５８】
＜Ｂ−３．効果＞
本発明にかかる実施の形態２によれば、メトリクス算出装置において、算出部に含まれる部分指標値算出部１３は、構文木内の一部の分岐命令文数および繰返命令文数を積算して、プログラムの部分メトリクスを算出することが可能であり、第１反映部としての累積指標値算出部４は、構文木内の一部において、分岐命令文内にさらに分岐命令文が含まれる場合、および、繰返命令文内にさらに繰返命令文が含まれる場合には、その重畳数に応じた値を部分メトリクスに反映させることで、プログラム中の指標値（メトリクス）を例えば行ごとに算出することができ、長い関数等が含まれるようなプログラムでも、問題がある部分を容易に把握することができ、問題箇所を特定することが容易となる。
【００５９】
また、本発明にかかる実施の形態２によれば、メトリクス算出装置において、算出部に含まれる部分指標値算出部１３は、構文木内の一部の分岐命令文数および繰返命令文数を積算して、プログラムの部分メトリクスを算出することが可能であり、反映部または第２反映部としての関数累積指標値算出部５は、構文木内の一部に関数の呼び出し命令文が含まれる場合、当該関数に含まれる分岐命令文数および繰返命令文数を、部分メトリクスに反映させることで、プログラム中の指標値（メトリクス）を例えば行ごとに算出することができ、長い関数等が含まれるようなプログラムでも、問題がある部分を容易に把握することができ、問題箇所を特定することが容易となる。
【符号の説明】
【００６０】
１  ソースプログラム、２  構文解析部、３  指標値算出部、４  累積指標値算出部、５  関数累積指標値算出部、６  算出結果、７  計算機、８  中央演算装置、９  主記憶装置、１０  記憶装置、１１  入力装置、１２  表示装置、１３  部分指標値算出部、１４  部分指標値記憶部、１５  部分指標値提示部。
【図１】
2011257965.tif 000003
【図２】
2011257965.tif 000004
【図３】
2011257965.tif 000005
【図４】
2011257965.tif 000006
【図５】
2011257965.tif 000007
【図６】
2011257965.tif 000008
【図７】
2011257965.tif 000009
【図８】
2011257965.tif 000010
【図９】
2011257965.tif 000011
【図１０】
2011257965.tif 000012
【図１１】
2011257965.tif 000013
【図１２】
2011257965.tif 000014
【図１３】
2011257965.tif 000015
【図１４】
2011257965.tif 000016
【図１５】
2011257965.tif 000017
【図１６】
2011257965.tif 000018
【図１７】
2011257965.tif 000019
【図１８】
2011257965.tif 000020