(57)【要約】【課題】動的型付き言語のソースコードを解析する際の誤列挙及び列挙漏れを抑制する。【解決手段】解析方法は、コンピュータが、プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成する。解析方法は、コンピュータが、データの流れと処理の流れとを用いて、動的型の参照解決と名前解決を実行する。解析方法は、コンピュータが、有向グラフをプログラムの関数単位で縮約する。さらに、解析方法は、コンピュータが、縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する。【選択図】図４
2019061587.tif 000002
【特許請求の範囲】
【請求項１】
動的型付き言語のプログラムを静的に解析する解析方法において、
プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成し、
前記データの流れと前記処理の流れとを用いて、動的型の参照解決と名前解決を実行し、
前記有向グラフをプログラムの関数単位で縮約し、
前記縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する
処理をコンピュータが実行する解析方法。
【請求項２】
前記生成する処理は、前記処理に対応する第１ノードと、前記データの参照に対応する第２ノードと、前記データの設定に対応する第３ノードとの接続関係を示す３部グラフを生成することを特徴とする請求項１に記載の解析方法。
【請求項３】
前記生成する処理は、前記第２ノード及び前記第３ノードとして、環境を渡すノードを含む前記３部グラフを生成することを特徴とする請求項２に記載の解析方法。
【請求項４】
前記探索する処理は、前記有向グラフを、前記解析指示を受けた関数の呼出先となるソースコードから生成された有向グラフの一部又は全部と結合し、結合された新たな有向グラフを用いて前記データの処理の流れを探索することを特徴とする請求項１乃至３のいずれか１つに記載の解析方法。
【請求項５】
前記探索する処理により探索された、前記関数に渡される値の候補を出力する処理をさらに含むことを特徴とする請求項１乃至４のいずれか１つに記載の解析方法。
【請求項６】
前記探索する処理は、前記関数の呼出し時に参照されるオブジェクトの設定値候補を列挙することにより、前記関数が所属するクラスを特定することを特徴とする請求項１乃至５のいずれか１つに記載の解析方法。
【請求項７】
前記探索する処理は、前記有向グラフのうち、前記設定値候補の列挙対象の変数・引数が現れる関数に関連する部分に探索範囲を限定することを特徴とする請求項６に記載の解析方法。
【請求項８】
プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成する生成部と、
前記データの流れと前記処理の流れとを用いて、動的型の参照解決と名前解決を実行する解決部と、
前記有向グラフをプログラムの関数単位で縮約する縮約部と、
前記縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する探索部と
を含む解析装置。
【請求項９】
コンピュータに、
プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成し、
前記データの流れと前記処理の流れとを用いて、動的型の参照解決と名前解決を実行し、
前記有向グラフをプログラムの関数単位で縮約し、
前記縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する
処理を行わせる解析プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、解析方法、解析装置及び解析プログラムに関する。
【背景技術】
【０００２】
ソースコードを解析して、変数や関数引数の設定元や取りうる値の候補を列挙する技術が知られている。例えば、ソースコードにエラーがある場合やソースコード作成規約に適合していない箇所がある場合に、修正箇所が広範囲におよぶ場合であっても、ソースコードをソースコード作成規約に従って変換するソースコード変換装置が知られている。当該装置は、ソースコードの全てについて、事前に構造及び呼出関係の解析を行い、ソースコードの解析結果に基づいて変換対象となる箇所の抽出を行う。そして、当該装置は、抽出された変換対象箇所に対応するソースコードの書き換え対象箇所を特定し、該当箇所のソースコードの書き換えを行う。
【０００３】
また、ユーザの判定作業を排除し、プログラムの検証を効率化することのできるプログラム検証装置も知られている。当該装置は、プログラムを抽象構文木に変換し、プログラム抽象構文木とする。当該装置は、内部仕様を抽象構文木に変換し、仕様抽象構文木とする。当該装置は、プログラム抽象構文木と仕様抽象構文木とを比較し、検証対象プログラムが内部仕様を満足するかを検証する。当該装置は、検証対象プログラムが内部仕様を満足することができなかった場合は、検証結果をプログラムの誤り位置として示す検証結果報告書を出力する。
【０００４】
さらに、人手で実施されたリファクタリングに対する等価性検証を、記号実行により行うときに、計算量を爆発させずに、迅速に行えるようにする検証装置も知られている。当該装置は、ソースコードの等価性を検証する際に、ソースコードを解析した構造グラフを用いた構造比較による検証と記号実行による検証の二種類の検証を行う。当該装置は、構造グラフによる構造比較によって構造が一致すると判定できる場合は、記号実行を行わない。また、当該装置は、構造比較による検証の前には、リファクタリング前後の各々のソースコードを、リファクタリングパターンごとに定められた正規化情報に基づき、構造グラフを正規化し、リファクタリングが正当なときには、構造が一致するように調整する。さらに、当該装置は、リファクタリング前後の各々の構造グラフを抽象化したものを記号実行して検証することにより、記号実行を行う箇所を限定する。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２０１４−１３４９６２号公報
【特許文献２】特開２０１１−２１５９９８号公報
【特許文献３】国際公開第２０１５／０２９１５４号
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかし、上記技術においては、ソースコードの変数や関数引数の設定元や取りうる値の候補を、誤列挙又は列挙漏れなく列挙することが難しい。例えば、ソースコードをコンパイルする等して実行可能な状態として、動的に解析する場合、誤列挙は生じないが、実際に実行した内容しか結果が戻らないため、列挙漏れが生じる場合がある。また、ソースコードを構文解析して静的に解析する場合において、同一クラスの別オブジェクトを同一オブジェクトとして扱い、また関数内の実行順序を無視すると、列挙漏れは生じないが、誤列挙が生じる場合がある。
【０００７】
一つの側面では、動的型付き言語のソースコードを解析する際の誤列挙及び列挙漏れを抑制できる解析方法、解析装置及び解析プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００８】
一つの態様において、解析方法は、コンピュータが、プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成する。解析方法は、コンピュータが、データの流れと処理の流れとを用いて、動的型の参照解決と名前解決を実行する。解析方法は、コンピュータが、有向グラフをプログラムの関数単位で縮約する。さらに、解析方法は、コンピュータが、縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する。
【発明の効果】
【０００９】
一つの態様によれば、動的型付き言語のソースコードを解析する際の誤列挙及び列挙漏れを抑制できる。
【図面の簡単な説明】
【００１０】
【図１】図１は、動的型付き言語と静的型付き言語との値の差異の一例を示す図である。
【図２】図２は、構文木の一例を示す図である。
【図３】図３は、有向グラフの一例を示す図である。
【図４】図４は、実施例１における解析装置の一例を示す図である。
【図５】図５は、実施例１におけるクラステーブルの一例を示す図である。
【図６】図６は、実施例１におけるノード関係テーブルの一例を示す図である。
【図７】図７は、実施例１におけるノードテーブルの一例を示す図である。
【図８】図８は、実施例１におけるエッジテーブルの一例を示す図である。
【図９】図９は、実施例１における書換規則の一例を示す図である。
【図１０】図１０は、グラフ要素の一例を示す図である。
【図１１】図１１は、実施例１におけるソースコード変換結果の一例を示す図である。
【図１２】図１２は、実施例１におけるソースコード変換結果の別の一例を示す図である。
【図１３】図１３は、ソースコード１の解決処理の一例を示す図である。
【図１４】図１４は、ソースコード１の縮約処理の一例を示す図である。
【図１５Ａ】図１５Ａは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１５Ｂ】図１５Ｂは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１５Ｃ】図１５Ｃは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１５Ｄ】図１５Ｄは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１５Ｅ】図１５Ｅは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１５Ｆ】図１５Ｆは、ソースコード３の解決処理及び縮約処理の一例を示す図である。
【図１６Ａ】図１６Ａは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｂ】図１６Ｂは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｃ】図１６Ｃは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｄ】図１６Ｄは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｅ】図１６Ｅは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｆ】図１６Ｆは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１６Ｇ】図１６Ｇは、ソースコード３の列挙処理及び結合処理の一例を示す図である。
【図１７】図１７は、実施例１における解析処理の一例を示すフローチャートである。
【図１８】図１８は、実施例１における変換処理の一例を示すフローチャートである。
【図１９】図１９は、実施例１における解決処理の一例を示すフローチャートである。
【図２０】図２０は、実施例１における縮約処理の一例を示すフローチャートである。
【図２１】図２１は、実施例１における列挙処理の一例を示すフローチャートである。
【図２２】図２２は、実施例１における結合処理の一例を示すフローチャートである。
【図２３】図２３は、実施例２におけるソースコード変換結果の一例を示す図である。
【図２４】図２４は、実施例２におけるソースコード変換結果の別の一例を示す図である。
【図２５Ａ】図２５Ａは、ソースコード５の列挙処理及び統合処理の一例を示す図である。
【図２５Ｂ】図２５Ｂは、ソースコード５の列挙処理及び統合処理の一例を示す図である。
【図２６】図２６は、解析プログラムを実行するコンピュータの一例を示す図である。
【発明を実施するための形態】
【００１１】
以下に、本願の開示する解析方法、解析装置及び解析プログラムの実施例を図面に基づいて詳細に説明する。なお、この実施例によりこの発明が限定されるものではない。また、以下に示す各実施例は、矛盾を起こさない範囲で適宜組み合わせても良い。
【実施例１】
【００１２】
本実施例における、後に説明する解析装置１００は、動的型付き言語のソースコードを解析対象とする。図１は、動的型付き言語と静的型付き言語との値の差異の一例を示す図である。図１に示す動的型付き言語のソースコード９１００及び静的型付き言語のソースコード９２００は、いずれも２つのクラス「Ｃ」及び「Ｄ」を含む。また、２つのクラス「Ｃ」及び「Ｄ」は、それぞれ同じ名前の関数「ｆ」を含む。
【００１３】
図１に示すように、静的型付き言語のソースコード９２００においては、オブジェクトを生成する際に、オブジェクトの「型」がソースコード中に明記される。例えば、静的型付き言語のソースコード９２００においては、オブジェクト「ｏ」の変数及び引数の型は、クラス「Ｃ」で定義され、オブジェクト「ｏ２」の変数及び引数の型は、クラス「Ｄ」で定義されることが明確に特定できる。この場合において、関数「ｓｅｎｄ」のパラメータ値の候補は「３」のみとなる。また、ソースコード９２０１に示すように、同じ名前のオブジェクト「ｏ」を生成する場合も、それぞれの変数及び引数の型は、ソースコードにおいて明確に定義される。
【００１４】
一方、動的型付き言語のソースコード９１００においては、オブジェクトを生成する際に、オブジェクトの「型」がソースコード中に明記されない。例えば、静的型付き言語のソースコード９２００においては、オブジェクト「ｏ」の変数及び引数の型が、クラス「Ｃ」で定義されるか、クラス「Ｄ」で定義されるかが明確に特定されていない。この場合において、関数「ｓｅｎｄ」のパラメータ値は、実行文の順序に応じて、「３」だけでなく「８」も候補となる場合がある。
【００１５】
このように、動的型付き言語においては、実行文の順序に応じてパラメータ値の候補が異なる場合がある。この場合、同一クラスの別オブジェクトを、同じオブジェクトとして扱い、実行順序を無視してプログラムを静的に解析する（いわゆる「曖昧な静的解析」をする）と、候補値の誤列挙が生じる場合がある。一方、動的型付き言語のソースコードをコンパイルするなどして実行可能な状態において値の候補を列挙する場合、候補値の誤列挙は生じないが、候補値の列挙漏れが生じる場合がある。
【００１６】
本実施例における解析装置１００は、プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成し、データの流れと処理の流れとを用いて、動的型の参照解決と名前解決を実行する。また、解析装置１００は、有向グラフをプログラムの関数単位で縮約し、縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する。
【００１７】
解析装置１００によるソースコードの処理について、図２乃至図３を用いて説明する。図２は、構文木の一例を示す図である。図２に示すように、解析装置１００は、符号１０００で示す動的型付き言語で記述されたソースコード１から、例えば後に説明するような処理により、アセンブラでの命令列の粒度で、構文木１０１０を生成する。
【００１８】
また、解析装置１００は、生成された構文木１０１０から、さらに図３に示すような有向グラフ１１００を生成する。図３は、有向グラフの一例を示す図である。図３において、有向グラフ１１００は、処理に対応する第１ノード１１１１及び１１１４と、データの参照に対応する第２ノード１１１２及び１１１５と、データの設定に対応する第３ノード１１１６とを含む。
【００１９】
本実施例における有向グラフ１１００は、例えば図３に示すように、第１ノード乃至第３ノードとエッジとを有する３部グラフである。図３においては、第２ノードを円形状で示すとともに、円形内に「１」などの正の値を示す。また、図３においては、第３ノードを円形状で示すとともに、円形内に「−１」などの負の値を示す。なお、図３に示すように、以下において、第１ノード１１１４から第２ノード１１１５へのエッジ１１１７、及び第３ノード１１１６から第１ノード１１１４へのエッジ１１１８の表記を省略する場合がある。
【００２０】
図３に示す第２ノード及び第３ノードは、関数内のデータの流れ（記憶領域の参照更新、処理の入出力値）と処理の流れとを示す。第２ノード及び第３ノードにおいて、絶対値が「１」であるノードは環境を示し、絶対値が「２」以上であるノードはパラメータを示す。
【００２１】
また、解析装置１００は、図３に示すような有向グラフに対して、データの流れと処理の流れとの両方を用いて、参照解決と名前解決を行う。解析装置１００は、解決結果を関数単位で縮約して保持する。さらに、解析装置１００は、縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する。
【００２２】
このように、本実施例における解析装置１００は、関数内のデータの流れと処理の流れとを有向グラフで示して参照解決と名前解決を実行し、解析対象の関数のデータの流れ及び処理の流れをたどるので、動的型付言語解析時の列挙漏れや誤列挙を抑制できる。
【００２３】
［機能ブロック］
次に、本実施例における解析装置１００について、図４を用いて説明する。図４は、実施例１における解析装置の一例を示す図である。図４に示すように、本実施例における解析装置１００は、通信部１１０と、記憶部１２０と、制御部１３０とを有する。
【００２４】
通信部１１０は、有線又は無線を問わず、図示しない外部のサーバや、図示しない解析装置１００の利用者や管理者の端末など、その他のコンピュータ等との通信を制御する。通信部１１０は、例えばＮＩＣ（Network  Interface  Card）等の通信インタフェース等である。
【００２５】
記憶部１２０は、例えば制御部１３０が実行するプログラムなどの各種データなどを記憶する。また、記憶部１２０は、ソースコードＤＢ１２１、クラス定義ＤＢ１２２、元フローＤＢ１２３、解決済みフローＤＢ１２４、書換規則ＤＢ１２５、縮約済みフローＤＢ１２６及び値候補ＤＢ１２７を有する。記憶部１２０は、ＲＡＭ（Random  Access  Memory）、ＲＯＭ（Read  Only  Memory）、フラッシュメモリなどの半導体メモリ素子や、ＨＤＤ（Hard  Disk  Drive）などの記憶装置に対応する。なお、以下の説明では、データベースを「ＤＢ」と表記する場合がある。
【００２６】
ソースコードＤＢ１２１は、解析対象とするプログラムのソースコードを記憶する。なお、ソースコードＤＢ１２１に記憶される情報は、例えば後に説明する取得部１３１により入力される。
【００２７】
クラス定義ＤＢ１２２は、ソースコードから有向グラフを生成する際に用いられる各クラスの定義に関する情報を記憶する。クラス定義ＤＢ１２２は、クラスの定義に関する情報として、例えば図５に示すようなクラステーブル１２２−１と、図６に示すようなノード関係テーブル１２２−２とを記憶する。なお、クラス定義ＤＢ１２２に記憶される情報は、例えば図示しない解析装置１００の管理者により予め入力される。
【００２８】
図５は、実施例１におけるクラステーブルの一例を示す図である。図５に示すように、クラステーブル１２２−１は、各ノードの名前と、当該名前のノードが示す内容とを対応付けて記憶する。例えば、クラス「λＩ＆」は、当該ノードが「クラスメンバ関数の処理内容を定義する」クラスのノードであることを示す。
【００２９】
図６は、実施例１におけるノード関係テーブルの一例を示す図である。図６に示すように、ノード関係テーブル１２２−２は、クラステーブルに列挙された各クラスのノードに対応する第２ノード及び第３ノードの属性を示す。図６に示すように、第２ノード及び第３ノードの属性は、絶対値「１」で示される「環境」、絶対値「２」以降で示される「パラメータ」に加えて、「メモリ領域」を示す「ｐｌｃ」、「名前空間」を示す「ｄｅｆ」などをさらに含む。また、クラス「λＩ＆」の第２ノード及びクラス「Ｒ＆」の第３ノードに示されるように、絶対値が最も大きい属性は、「継続」を示す場合がある。
【００３０】
図４に戻って、元フローＤＢ１２３は、後に説明する変換部１３２により、ソースコードから生成される有向グラフに関する情報を記憶する。元フローＤＢ１２３は、例えば図７に示すような有向グラフを構成するノードに関する情報を記憶するノードテーブル１２３−１と、図８に示すような有向グラフを構成するエッジに関する情報を記憶するエッジテーブル１２３−２とを有する。なお、元フローＤＢ１２３に記憶される情報は、例えば変換部１３２により入力される。
【００３１】
図７は、実施例１におけるノードテーブルの一例を示す図である。図７に示すように、ノードテーブル１２３−１は、例えば、「格納位置」と、「ノード種類」と、「クラス」と、「属性」とを、「ＩＤ」に対応付けて記憶する。
【００３２】
図７において、「ＩＤ」は、ノードを一意に識別する識別子（Identifier）を示す。「格納位置」は、当該ノードに対応するソースコードが格納された位置を示す。「ノード種類」は、当該ノードが、図３に示す第１ノード乃至第３ノードのいずれに該当するかを示す。
【００３３】
図７において、「クラス」は、当該ノードがどのクラスに該当するかを示す。なお、クラスは、「ノード種類」が「１」であるノードについてのみ記憶される。「属性」は、当該ノードの属性を示す。例えば「ノード種類」が「１」であるノードの「属性」は、「‘ｈｔｔｐ：／／’」などの文字列や、「ｓｅｌｆ」などの関数名を記憶する。また、例えば「ノード種類」が「２」又は「３」であるノードの「属性」は、「１」や「−１」など、「環境」や「パラメータ」などの属性を記憶する。なお、後に説明するように、「ノード種類」が「２」又は「３」であるノードの「属性」は、メモリ領域を示す「ｐｌｃ」や、名前空間を示す「ｄｅｆ」などの属性も含む。
【００３４】
例えば、図７に示すように、ＩＤが「１１」のノードは、第１ノードｎ１であり、クラスが「ＩＶ」であり、属性が「‘ｈｔｔｐ：／／’」である。また、ＩＤが「１１」のノードに対応するソースコードは、「／ｓｒｃ／ｒｅｖ．１／」に格納されている。
【００３５】
図８は、実施例１におけるエッジテーブルの一例を示す図である。図８に示すように、エッジテーブルは、「起点ＩＤ」と「終点ＩＤ」とを対応付けて記憶する。図８において、「起点ＩＤ」は、当該エッジの起点となるノードのＩＤを示し、「終点ＩＤ」は、当該エッジの終点となるＩＤを示す。
【００３６】
図４に戻って、解決済みフローＤＢ１２４は、後に説明する解決部１３３により、参照解決及び名前解決を行う解決処理が行われた結果である有向グラフに関する情報を記憶する。解決済みフローＤＢ１２４は、例えば図７に示すノードテーブル１２３−１及び図８に示すエッジテーブル１２３−２と同様に、有向グラフを構成するノード及びエッジに関する情報を記憶する。なお、解決済みフローＤＢ１２４に記憶される情報は、例えば後に解決部１３３により入力される。
【００３７】
書換規則ＤＢ１２５は、有向グラフに対する、後に説明する解決処理、縮約処理及び結合処理に適用される書換規則に関する情報を記憶する。なお、書換規則ＤＢ１２５に記憶される情報は、例えば図示しない解析装置１００の管理者により予め入力される。
【００３８】
図９は、実施例１における書換規則の一例を示す図である。図９に示すように、書換規則は、「内容」と、「種別」と、「優先度」とを「タイトル」に対応付けて記憶する。図９において、「タイトル」は、書換種別を一意に識別する情報である。「内容」は、当該タイトルの書換規則が適用される有向グラフの対象及び条件、並びに書換処理の内容を示す。
【００３９】
図９において、「種別」は、当該書換規則を行う処理の種別を示す。なお、本実施例において、種別「Ｓ」は解決処理に適用される書換規則を示し、種別「Ｄ」は縮約処理に適用される書換規則を示し、種別「Ｍ」は統合処理に適用される書換規則を示す。また、「優先度」は、当該書換規則が適用される順序を示す。本実施例においては、書換規則は、優先度が高い、すなわち優先度の値が小さいものから順に適用される。
【００４０】
図４に戻って、縮約済みフローＤＢ１２６は、後に説明する縮約部１３４による縮約処理が行われた結果である有向グラフに関する情報を記憶する。縮約済みフローＤＢ１２６は、例えば図７に示すノードテーブル１２３−１及び図８に示すエッジテーブル１２３−２と同様に、有向グラフを構成するノード及びエッジに関する情報を記憶する。なお、縮約済みフローＤＢ１２６に記憶される情報は、例えば縮約部１３４により入力される。
【００４１】
値候補ＤＢ１２７は、後に説明する列挙処理の結果である値に関する情報を記憶する。値候補ＤＢ１２７は、対象となる関数において、引数又は変数の設定値の候補となる値を記憶する。なお、値候補ＤＢ１２７に記憶される情報は、例えば後に説明する列挙部１３５により入力される。
【００４２】
図４に戻って、制御部１３０は、解析装置１００の全体的な処理を司る処理部である。制御部１３０は、例えば、ＣＰＵ（Central  Processing  Unit）やＭＰＵ（Micro  Processing  Unit）等によって、内部の記憶装置に記憶されているプログラムがＲＡＭを作業領域として実行されることにより実現される。また、制御部１３０は、例えば、ＡＳＩＣ（Application  Specific  Integrated  Circuit）やＦＰＧＡ（Field  Programmable  Gate  Array）等の集積回路により実現されるようにしてもよい。
【００４３】
制御部１３０は、取得部１３１、変換部１３２、解決部１３３、縮約部１３４、列挙部１３５及び出力部１３６を有する。なお、取得部１３１、変換部１３２、解決部１３３、縮約部１３４、列挙部１３５及び出力部１３６は、プロセッサが有する電子回路の一例やプロセッサが実行するプロセスの一例である。
【００４４】
取得部１３１は、ソースコード及び解析対象の関数に関する情報を取得する。取得部１３１は、例えば通信部１１０を通じて、図示しない外部のサーバや利用者の端末から、ソースコードを取得し、ソースコードＤＢ１２１に記憶する。
【００４５】
また、取得部１３１は、通信部１１０を通じて、例えば利用者の端末から解析対象の関数に関する指示を受け付ける。取得部１３１は、変換部１３２に対して、解析対象の関数に関する有向グラフの生成指示を出力するとともに、列挙部１３５に解析対象の関数を特定する情報を出力する。
【００４６】
次に、変換部１３２は、ソースコードを、図３に示すような有向グラフに変換する。なお、変換部１３２は、生成部の一例である。
【００４７】
変換部１３２は、取得部１３１から有向グラフの生成指示の出力を受けると、ソースコードＤＢ１２１から解析対象の関数を含むソースコードを抽出し、例えば図１０に示すようなグラフ要素を特定して、図２に示すような構文木を生成する。
【００４８】
図１０は、グラフ要素の一例を示す図である。変換部１３２は、図１０に示すような節点に対応する要素をソースコード中から特定し、図２に示すような構文木を生成する。さらに、変換部１３２は、生成された構文木を、図３に示すような有向グラフの形に変換し、元フローＤＢ１２３に記憶する。
【００４９】
変換部１３２が生成する有向グラフは、例えばソースコードをアセンブラの粒度で分解したものである。すなわち、生成された有向グラフは、参照先のレジスタやメモリアドレスが特定できる形で、データの流れ及び処理の流れを示したものである。
【００５０】
変換部１３２により生成される有向グラフについて、図１１及び図１２を用いて説明する。図１１は、実施例１におけるソースコード変換結果の一例を示す図である。符号２０００に示す変換元となるソースコード２は、図２に示すソースコード１と同名のクラスであるが、関数「＿＿ｉｎｉｔ＿＿」２００１に加えて、別の関数「ｎｅｗＳｐａｃｅ」２００２をさらに定義している。
【００５１】
この場合において、変換部１３２は、関数「＿＿ｉｎｉｔ＿＿」２００１に対応するノード「λＩ＆」２１０１に加えて、別の関数「ｎｅｗＳｐａｃｅ」２００２に対応するノード「λＩ＆」２１０２をさらに含む有向グラフ２１００を生成する。
【００５２】
図１２は、実施例１におけるソースコード変換結果の別の一例を示す図である。符号３０００に示すソースコード３は、クラス「Ｐｒｏｘｙ」のオブジェクト「ｐ」を生成する命令３００１を含む。
【００５３】
この場合において、変換部１３２は、値の参照先「ＲＩ」としてクラス「Ｐｒｏｘｙ」を示すノード３１０１を含む有向グラフ３１００を生成する。なお、ノード３１０１の参照先を特定する処理については、後に説明する。
【００５４】
次に、解決部１３３は、有向グラフに対して参照解決及び名前解決を行う解決処理を実行する。解決部１３３は、元フローＤＢ１２３から有向グラフに関する情報を読み出し、書換規則ＤＢ１２５に記憶された種別「Ｓ」の書換規則を有向グラフに適用する。解決部１３３は、種別「Ｓ」の書換規則を適用した有向グラフに関する情報を、解決済みフローＤＢ１２４に記憶する。
【００５５】
本実施例における解決処理について、図１３を用いて説明する。図１３は、ソースコード１の解決処理の一例を示す図である。図１３に示す有向グラフ１２００は、図３に示す有向グラフ１１００のレイアウトを変更したもので、ノード及びエッジの構成は有向グラフ１１００と同様である。なお、以下の有向グラフを示す図面において、次の処理対象となるノード又はエッジを破線で示し、前の処理により変更されたノード又はエッジを太線で示す場合がある。
【００５６】
まず、解決部１３３は、書換規則ＤＢ１２５を参照し、元フローＤＢ１２３に記憶される有向グラフ１２００に含まれる主ノードλＩ＆「＿＿ｉｎｉｔ＿＿」（コンストラクタのメソッド名）に種別「Ｓ」の書換規則を適用する。まず、解決部１３３は、書換規則ＤＢ１２５に記憶される種別「Ｓ」の書換規則のうち、最も優先度が高い、すなわち優先度の値が最も小さい「Ｍ＿Ｉ」を有向グラフ１２００に適用するか否かを判定する。
【００５７】
この場合において、有向グラフ１２００は対象となるグラフ形状「Ａ＆（−２）→（２）Ｐ（−ｐｌｃ）→（＋ｐｌｃ）Ｃｌａｓｓ」を含まないので、解決部１３３は、書換規則「Ｍ＿Ｉ」を有向グラフ１２００に対して適用しない。
【００５８】
次に、解決部１３３は、書換規則ＤＢ１２５に記憶された種別「Ｓ」の書換規則のうち、２番目に優先度が高い書換規則「ＲＩ＿Ｅ（１）」を有向グラフ１２００に適用するか否かを判定する。この場合において、有向グラフ１２００は対象となるグラフ形状「ＲＩ（−１）→（１）…（−１）→（１）λＩ＆」に該当するノード「ＲＩ」１２０１を含むので、解決部１３３は、書換規則「ＲＩ＿Ｅ（１）」を有向グラフ１２００に適用する。
【００５９】
すなわち、解決部１３３は、有向グラフ１２００のノード「ＲＩ」１２０１をノードＩＤ１３０１に変更する。また、解決部１３３は、ノードλＩ＆からノードＩＤ１３０１の第２ノードへのエッジ１３２３を追加することにより、有向グラフ１２００を有向グラフ１３００に変換する。
【００６０】
同様に、解決部１３３は、変換された有向グラフ１３００が、さらに別のノード「ＲＩ」１３１１を含むので、解決部１３３は、書換規則「ＲＩ＿Ｅ（１）」を有向グラフ１３００にも適用する。
【００６１】
すなわち、解決部１３３は、有向グラフ１３００のノード「ＲＩ」１３１１をノードＩＤ１４１１に変更する。また、解決部１３３は、ノード「λＩ＆」からノードＩＤ１４１１の第２ノードへのエッジ１４３３を追加することにより、有向グラフ１３００を有向グラフ１４００に変換する。
【００６２】
また、解決部１３３は、変換された有向グラフ１４００は、書換規則「ＲＩ＿Ｅ（１）」の対象となるグラフ形状に該当するノードを含まないと判定する。この場合、解決部１３３は、書換規則ＤＢ１２５に記憶された、優先度が書換規則「ＲＩ＿Ｅ（１）」以下であるその他の種別「Ｓ」の書換規則を、有向グラフ１４００に適用するか否かを判定する。
【００６３】
この場合において、有向グラフ１４００は、その他の種別「Ｓ」の書換規則の対象となるグラフ形状を含んでいないため、解決部１３３はその他の種別「Ｓ」の書換規則を有向グラフ１４００に適用しない。そして、解決部１３３は、全ての種別「Ｓ」の書換規則について、有向グラフ１４００に適用するか否かを判定した後に、変換された有向グラフ１４００を、解決済みフローＤＢ１２４に記憶する。
【００６４】
次に、縮約部１３４は、解決済みの有向グラフを、プログラムの関数単位で縮約する縮約処理を実行する。縮約部１３４は、解決済みフローＤＢ１２４から有向グラフに関する情報を読み出し、書換規則ＤＢ１２５に記憶された種別「Ｄ」の書換規則を有向グラフに適用する。縮約部１３４は、種別「Ｄ」の書換規則を適用した有向グラフに関する情報を、縮約済みフローＤＢ１２６に記憶する。
【００６５】
本実施例における縮約処理について、図１４を用いて説明する。図１４は、ソースコード１の縮約処理の一例を示す図である。まず、縮約部１３４は、書換規則ＤＢ１２５を参照し、解決済みフローＤＢ１２４に記憶される有向グラフ１４００に含まれる主ノード「λＩ＆」である「＿＿ｉｎｉｔ＿＿」に、種別「Ｄ」の書換規則を適用する。まず、縮約部１３４は、書換規則ＤＢ１２５に記憶される種別「Ｄ」の書換規則のうち、最も優先度が高い、すなわち優先度の値が最も小さい「ＩＤ＿Ｅ」を有向グラフ１４００に適用するか否かを判定する。この場合において、有向グラフ１４００は対象となるグラフ形状「ＩＤ」を含むので、縮約部１３４は、書換規則「ＩＤ＿Ｅ」を有向グラフ１４００に適用する。
【００６６】
すなわち、縮約部１３４は、有向グラフ１４００のノード「ＩＤ」１４０１を削除するとともに、図１３に示すノード「ＩＤ」１４０１に隣接するエッジ１４１２、１４１３、１４２２及び１４２３を削除する。また、縮約部１３４は、削除された各エッジの接続先を相互に接続するエッジ１５１３及び１５２３を追加する。これにより、縮約部１３４は、有向グラフ１４００を有向グラフ１５００に変換する。
【００６７】
同様に、縮約部１３４は、有向グラフ１５００にも、さらに書換規則「ＩＤ＿Ｅ」を適用することにより、ノード「ＩＤ」１５１１、並びにエッジ１５１２、１５１３、１５３２及び１５３３を削除するとともに、エッジ１６１３及び１６３３を追加する。これにより、縮約部１３４は、有向グラフ１５００を有向グラフ１６００に変換する。
【００６８】
また、縮約部１３４は、書換規則ＤＢ１２５に記憶された、優先度が書換規則「ＩＤ＿Ｅ」以下であるその他の種別「Ｄ」の書換規則を、有向グラフ１６００に適用するか否かを判定する。この場合において、有向グラフ１６００は、その他の種別「Ｄ」の書換規則の対象となるグラフ形状を含んでいないため、縮約部１３４はその他の種別「Ｄ」の書換規則を有向グラフ１４００に適用しない。そして、縮約部１３４は、全ての種別「Ｄ」の書換規則について、有向グラフ１６００に適用するか否かを判定した後に、変換された有向グラフ１６００を、縮約済みフローＤＢ１２６に記憶する。
【００６９】
本実施例による解決部１３３及び縮約部１３４による処理の別の一例について、図１５Ａ乃至図１５Ｆを用いて説明する。図１５Ａ乃至図１５Ｆは、ソースコード３の解決処理及び縮約処理の一例を示す図である。まず、解決部１３３は、図１２に示すソースコード３から生成された有向グラフ３１００に対し、種別「Ｓ」の書換規則を適用する。この場合において、解決部１３３は、書換規則「ＲＩ＿Ｅ（１）」を、対象となるグラフ形状に該当するノード「ＲＩ」３１０１に適用する。
【００７０】
また、縮約部１３４は、解決部１３３により書換規則「ＲＩ＿Ｅ（１）」が適用された有向グラフ３１００に対し、さらに種別「Ｄ」の書換規則を適用する。この場合において、縮約部１３４は、書換規則「ＩＤ＿Ｅ」を有向グラフ３１００に適用することにより、解決及び縮約された有向グラフ３２００を生成する。
【００７１】
図１５Ａに示すように、有向グラフ３２００は、有向グラフ３１００に含まれるノード「ＲＩ」３１０１及び当該ノードの第２ノード及び第３ノードに接続するエッジ３１１２、３１１３及び３１３２が削除されている。また、有向グラフ３２００は、ノード「ＲＩ」３２１１の第２ノードに接続するエッジ３２１２と、ノード「λＩ＆」の第２ノード３１０９に接続するエッジ３２３３とが追加されている。
【００７２】
本実施例におけるソースコード３は、図１２に示すように、クラス「Ｐｒｏｘｙ」のオブジェクト「ｐ」を生成する命令３００１を含む。そこで、本実施例における列挙部１３５は、ソースコード３の参照解決及び名前解決に際し、クラス「Ｐｒｏｘｙ」を呼び出すノードを追加する。
【００７３】
図１５Ｂに移って、解決部１３３は、有向グラフ３２００に対し、さらに書換規則「ＲＩ＿Ｅ（２）」を適用する。これにより、解決部１３３は、有向グラフ３２００からクラス「Ｐｒｏｘｙ」に関するノード「ＲＩ」３２１１を削除する。また、解決部１３３は、主ノード「Ｃｌａｓｓ」３３２１、ノード「Ｐ」３３１１及び両ノードを接続するエッジ３３１３を追加することにより、有向グラフ３３００を生成する。
【００７４】
また、解決部１３３は、有向グラフ３３００に対し、さらに書換規則「Ｍ＿Ｉ」を適用する。これにより、解決部１３３は、有向グラフ３２００にノード「Ｍ」３４３１、ノード「ＲＭ」３４４１を追加することにより、有向グラフ３４００を生成する。
【００７５】
図１５Ｃに移って、解決部１３３は、有向グラフ３４００に対し、さらに書換規則「ＤＩ＿Ｉ」を適用する。これにより、解決部１３３は、有向グラフ３４００からノード「ＷＩ」３４５１を削除するとともに、ノード「ＤＩ」３５６１、ノード「ＷＩ」３５５１及び両ノードを接続するエッジを追加することにより、有向グラフ３５００を生成する。
【００７６】
また、解決部１３３は、有向グラフ３５００に対し、さらに書換規則「ＤＩ＿Ｅ」を適用する。これにより、解決部１３３は、有向グラフ３５００のノード「ＤＩ」３５６１及びノード「ＷＩ」３５５１を削除するとともに、ノード「Ｓ」３６６１及びノード「Ｕ」３６５１を追加することにより、有向グラフ３６００を生成する。
【００７７】
図１５Ｄに移って、解決部１３３は、有向グラフ３６００に対し、さらに書換規則「ＲＩ＿Ｉ（４）」及び「Ｐ．Ｅ＿Ｅ」を適用する。これにより、解決部１３３は、有向グラフ３４００からノード「ＲＩ」３６７１を削除するとともに、ノード「Ｐ」３７７１及びこれに接続するエッジを追加する。また、解決部１３３は、ノード「Ｓ」３６６１及びノード「Ｐ」３７７１を、第２ノード「＋ｐｌｃ」及び第３ノード「−ｐｌｃ」を介して接続する。さらに、解決部１３３は、ノード「Ｍ」３７８１とノード「ＲＭ」３７８９とを接続するエッジ３７８３を追加することにより、有向グラフ３７００を生成する。
【００７８】
また、解決部１３３は、有向グラフ３７００に対し、さらに書換規則「Ｍ＿Ｅ（３）」を適用する。これにより、解決部１３３は、有向グラフ３７００に、主ノード「Ｃｌａｓｓ」３８２１から第２ノード「＋ｄｅｆ」及び第３ノード「−ｄｅｆ」を介して接続されたノード「Ｓ」３８９１を追加する。また、解決部１３３は、有向グラフ３７００のノード「Ｍ」３７８１をノード「Ｐ」３８８１に置き換えて、有向グラフ３８００を生成する。なお、ノード「Ｓ」３８９１とノード「Ｍ」３７８１とは、第２ノード「１」及び第３ノード「−１」に加えて、第２ノード「＋ｐｌｃ」及び第３ノード「−ｐｌｃ」を介しても接続される。
【００７９】
図１５Ｅに移って、解決部１３３は、有向グラフ３８００に対し、さらに書換規則「ＣＬ＿Ｉ（４）」を適用する。これにより、解決部１３３は、「＿＿ｉｎｉｔ＿＿」メソッドに対応するノード「λＩ＆」３９０１を呼び出すノード「ＣＬ」３９１１を有向グラフ３８００に追加する。また、解決部１３３は、ノード「ＣＬ」３９１１に接続するエッジを修正して、有向グラフ３９００を生成する。これにより、解決部１３３は、関数「Ｃｌｉｅｎｔ．ｇｅｔＲｅｓｏｕｒｃｅ」による、関数「Ｐｒｏｘｙ．＿＿ｉｎｉｔ＿＿」に対する呼出関係を有向グラフ３９００に記録する。
【００８０】
同様に、解決部１３３は、有向グラフ３９００に対し、さらに書換規則「ＣＬ＿Ｉ（４）」を適用して、「ｎｅｗＳｐａｃｅ」メソッドに対応するノード「λＩ＆」３Ａ０１を呼び出すノード「ＣＬ」３Ａ１１を有向グラフ３８００に追加する。また、解決部１３３は、ノード「ＣＬ」３Ａ１１に接続するエッジを修正して、有向グラフ３Ａ００を生成する。これにより、解決部１３３は、関数「Ｃｌｉｅｎｔ．ｇｅｔＲｅｓｏｕｒｃｅ」による、関数「Ｐｒｏｘｙ．ｎｅｗＳｐａｃｅ」に対する呼出関係を有向グラフ３Ａ００に記録する。
【００８１】
図１５Ｆに移って、縮約部１３４は、有向グラフ３Ａ００に対し、種別「Ｄ」の書換規則「ｕｎｒｅｆ＿Ｅ，Ｓ＿Ｕ＿Ｅ」を適用する。これにより、縮約部１３４は、有向グラフ３Ａ００から、ノード「ＲＭ」３Ａ２１及び３Ａ２２、ノード「Ｐ」３Ａ３１及び３Ａ３２、ノード「Ｕ」３Ａ４１及びノード「Ｓ」３Ａ５１を削除して、有向グラフ３Ｂ００を生成する。なお、有向グラフ６０００は、有向グラフ３Ｂ００のレイアウトを変更したもので、ノード及びエッジの構成は有向グラフ３Ｂ００と同様である。
【００８２】
図４に戻って、列挙部１３５は、縮約済みの有向グラフを用いて、対象となる関数の引数又は変数の設定値の候補となる値を列挙する。列挙部１３５は、取得部１３１から解析対象の関数を特定する情報の出力を受けると、特定された関数の値の候補値を列挙する。なお、列挙部１３５は、探索部の一例である。
【００８３】
列挙部１３５は、特定された関数に対して、呼出先のプログラムがあるか否かを判定する。列挙部１３５は、呼出先のプログラムがあると判定した場合、呼出先のプログラムの有向グラフを、呼出元のプログラムの有向グラフと結合する。
【００８４】
列挙部１３５は、関数の呼出元の有向グラフを列挙して、書換規則ＤＢ１２５を参照し、種別「Ｍ」の書換規則を呼出先の有向グラフと呼出元の有向グラフとに適用する。具体的には、列挙部１３５は、列挙対象とする引数又は変数を含む関数の呼出元を列挙し、各呼出元関数に対応する有向グラフの関数呼出部分を、呼出先の有向グラフと結合する。
【００８５】
例えば、列挙部１３５は、呼出先の有向グラフを、サブグラフとして呼出元の有向グラフに追加する。なお、サブグラフとして追加される呼出先の有向グラフは、例えば主ノードを「λＩ＆  ＄２」のように変更する。そして、列挙部１３５は、呼出元のグラフにおける、ノード「Ａ＆」に対して種別「Ｍ」の書換規則を適用する。また、列挙部１３５は、呼出元の有向グラフと呼出先の有向グラフとが結合されたグラフに対して、さらに種別「Ｍ」の書換規則を適用する。
【００８６】
また、列挙部１３５は、種別「Ｍ」の書換規則を適用した有向グラフに対して、種別「Ｓ」の書換規則を適用する解決処理と、種別「Ｄ」の書換規則を適用する縮約処理とを繰り返す。
【００８７】
また、列挙部１３５は、全ての呼出先の有向グラフを結合した場合、又は呼出先のプログラムが無いと判定した場合、有向グラフの関数に対して値を設定するノードを列挙し、Ｆノードをデータの流れ及び処理の流れとは逆方向に探索していく。列挙部１３５は、ＩＶノードに到達するまで探索を繰り返し、ＩＶノードに到達すると、列挙されたノードを文字列に変換する。
【００８８】
出力部１３６は、解析処理の結果を出力する。出力部１３６は、値候補ＤＢ１２７に記憶された引数又は変数の候補値を抽出し、例えば通信部１１０を通じて、図示しない利用者の端末に出力する。
【００８９】
本実施例における解析装置１００による列挙処理及び出力内容について、図１６Ａ乃至図１６Ｇを用いて説明する。図１６Ａ乃至図１６Ｇは、ソースコード３の列挙処理及び結合処理の一例を示す図である。以下においては、図１２に示すソースコード３により生成されるオブジェクト「ｐ」に含まれる「ｓｅｎｄ」関数に渡される引数の候補値を列挙する処理について説明する。
【００９０】
「ｓｅｎｄ」関数は、ソースコード３の「Ｃｌｉｅｎｔ」クラスに含まれる「Ｃｌｉｅｎｔ．ｇｅｔＲｅｓｏｕｒｃｅ」関数により呼び出される。しかし、「ｓｅｎｄ」関数は、ソースコード３ではなく、ソースコード２の「Ｐｒｏｘｙ」クラスに含まれている。そこで、本実施例における列挙部１３５は、呼出元であるソースコード３の有向グラフと、呼出先であるソースコード２の有向グラフとの結合処理を行う。
【００９１】
図１６Ａに示すように、列挙部１３５は、図１５Ｆに示すソースコード３の有向グラフ６０００に対して、種別「Ｍ」の書換規則「ＡＣ＿Ｅ」を適用する。まず、列挙部１３５は、図９に示す書換規則「ＡＣ＿Ｅ」の処理１．を実行することにより、ノード「λＩ＆」から始まるサブグラフを複製する。本実施例においては、列挙部１３５は、ソースコード２の「ｎｅｗＳｐａｃｅ」関数を定義するノード「λＩ＆」２２０１から始まるサブグラフ２２００を追加する。なお、図１６Ｂ以下においては、追加されたサブグラフ２２００のノード「λＩ＆」２２０１を、「λＩ＆  ＄２」と表す場合がある。これにより、列挙部１３５は、有向グラフ６０００とサブグラフ２２００とを含む有向グラフ６１００を生成する。
【００９２】
図１６Ｂに移って、列挙部１３５は、有向グラフ６１００に対して、種別「Ｍ」の書換規則「ＡＣ＿Ｅ」の処理２．１．を実行する。これにより、列挙部１３５は、有向グラフ６０００のノード「ＣＬ」６２２１からサブグラフ２２００のノード「ＲＩ」６２１１へ接続するエッジが追加された有向グラフ６２００を生成する。
【００９３】
また、列挙部１３５は、有向グラフ６２００に対して、書換規則「ＡＣ＿Ｅ」の処理２．２．及び処理２．３．１．を実行する。これにより、ノード「Ｐ」６３１１からノード「ＲＭ」６３１２へ接続するエッジ６３１３、及びノード「ＩＶ」６３２１からノード「Ｆ」６３２２へ接続するエッジ６３２３が追加される。さらに、列挙部１３５は、ノード「Ｒ＆」６３３１からノード「Ｒ＆」６３３２へ接続するエッジ６３３３が追加された有向グラフ６３００を生成する。なお、ソースコード３には、書換規則「ＡＣ＿Ｅ」の処理２．３．２．及び２．３．３．の対象となるノード又はエッジは含まれない。
【００９４】
図１６Ｃに移って、列挙部１３５は、有向グラフ６３００に対して、書換規則「ＡＣ＿Ｅ」の処理３．を実行する。これにより、列挙部１３５は、図１６Ｂに示すノード「λＩ＆」６３４１及び接続する各エッジが削除された有向グラフ６４００を生成する。
【００９５】
また、列挙部１３５は、有向グラフ６４００に対して、書換規則「ＡＣ＿Ｅ」の処理４．を実行する。これにより、列挙部１３５は、図１６Ｂに示すノード「Ｒ＆」６３３１及び接続する各エッジが削除された有向グラフ６５００を生成する。なお、列挙部１３５は、有向グラフ６５００において、削除されたノード「Ｒ＆」６３３１と接続されていたノード「Ａ＆」６４０１からノード「Ｒ＆」６３３２へ接続するエッジを追加する。
【００９６】
ところで、クラス「Ｐｒｏｘｙ」は、ソースコード２に加えて、ソースコード１にも定義されている。そこで、列挙部１３５は、呼出元であるソースコード３の有向グラフに、呼出先であるソースコード１の有向グラフをさらに結合する処理を行う。
【００９７】
図１６Ｄに移って、列挙部１３５は、有向グラフ６４００に対して、書換規則「ＡＣ＿Ｅ」の処理１．を実行する。これにより、列挙部１３５は、有向グラフ６５００に、ソースコード１の「＿＿ｉｎｉｔ＿＿」関数を定義するノード「λＩ＆  ＄２」１７０１から始まるサブグラフ１７００を追加した有向グラフ７０００を生成する。
【００９８】
図１６Ｅに移って、列挙部１３５は、有向グラフ７０００に対して、書換規則「ＡＣ＿Ｅ」の処理２．１．、２．２．、及び２．３．１．を実行する。これにより、列挙部１３５は、有向グラフ７０００に、ノード「ＣＬ」７１１１からノード「ＩＶ」７１１２へ接続するエッジ、及びノード「λＩ＆」７１２１からノード「Ｆ」７１２２へ接続するエッジを追加する。さらに、列挙部１３５は、有向グラフ７０００に、ノード「Ｒ＆」７１３１からノード「ＩＶ」７１３２へ接続するエッジ、及びノード「Ｐ」７１４１からノード「ＷＭ」７１４２へ接続するエッジを追加して、有向グラフ７１００を生成する。
【００９９】
図１６Ｆに移って、列挙部１３５は、有向グラフ７１００に対して、書換規則「ＡＣ＿Ｅ」の処理３．を実行する。これにより、列挙部１３５は、有向グラフ７０００から、ノード「λＩ＆  ＄２」７１５１及びノード「Ａ＆」７１６１を削除して、有向グラフ７２００を生成する。
【０１００】
さらに、列挙部１３５は、有向グラフ７２００に対して、書換規則「ＡＣ＿Ｅ」の処理４．、及び種別「Ｄ」の書換規則「ｕｎｒｅｆ＿Ｅ」を実行する。これにより、列挙部１３５は、有向グラフ７２００から、ノード「Ｒ＆」７１３１、ノード「λＩ＆」７２１１及び７２１２、ノード「ＣＬ」７２１１及び７２２２並びにノード「ＲＭ」７２３１を削除する。また、列挙部１３５は、削除される各ノードに接続するエッジを整理して、有向グラフ７３００を生成する。
【０１０１】
図１６Ｇに移って、列挙部１３５は、統合された有向グラフ７３００に対して、列挙処理を行う。有向グラフ７３００において、「ｓｅｎｄ」関数に関するノード「ＲＩ」７３１１は、ノード「Ａ＆」７３２１により参照される。また、ノード「Ａ＆」７３２１は、ノード「Ｆ」７３３１も参照している。そこで、列挙部１３５は、「ｓｅｎｄ」関数に関するノード「ＲＩ」７３１１と呼出関係にあるノードを列挙する。
【０１０２】
列挙部１３５は、ノード「Ｆ」７３３１に呼び出されるノード「Ｆ」７３４１及びノード「ＩＶ」７３３３を列挙する。また、列挙部１３５は、ノード「Ｆ」７３４１にさらに呼び出されるノード「Ｆ」７３５１及びノード「ＩＶ」７３４３を列挙する。さらに、列挙部１３５は、ノード「Ｆ」７３５１にさらに呼び出されるノード「λＩ＆」７３５３及びノード「ＩＶ」７３５２を列挙する。
【０１０３】
そして、列挙部１３５は、列挙されたノードを用いて、オブジェクト「ｐ」に含まれる「ｓｅｎｄ」関数に渡される引数の候補値を生成する。列挙部１３５は、ノード「ＩＶ」７３３３に対応する文字列「‘Ｆｏｏ’」７９３３と、ノード「ＩＶ」７３４３に対応する文字列「／ｃｒｅａｔｅ／ｓｐａｃｅ／」７９４３とを含む候補値を生成する。また、列挙部１３５は、候補値に、ノード「ＩＶ」７３５２に対応する文字列「‘ｈｔｔｐ：／／’」７９５２と、ノード「λＩ＆」７３５３に対応する変数「λＩ＆Ｃｌｉｅｎｔ．ｇｅｔＲｅｓｏｕｒｃｅ．３」７９５３とをさらに含める。
【０１０４】
そして、出力部１３６は、生成された候補値を含む出力画面７９９９を、例えば通信部１１０を通じて利用者の端末に出力する。
【０１０５】
［処理の流れ］
次に、本実施例における処理について、図１７乃至図２２を用いて説明する。図１７は、実施例１における解析処理の一例を示すフローチャートである。図１７に示すように、解析装置１００の取得部１３１は、例えば通信部１１０を通じて解析処理の開始指示を受け付けるまで待機する（Ｓ１００：Ｎｏ）。
【０１０６】
取得部１３１は、開始指示を受け付けたと判定した場合（Ｓ１００：Ｙｅｓ）、変換部１３２に対して、解析対象の関数に関する有向グラフの生成指示を出力するとともに、列挙部１３５に解析対象の関数を特定する情報を出力する。
【０１０７】
変換部１３２は、有向グラフの生成指示の出力を受けると、変換処理を開始する（Ｓ１１０）。図１８は、実施例１における変換処理の一例を示すフローチャートである。図１８に示すように、変換部１３２は、ソースコードＤＢ１２１から、解析対象の関数を含むソースコードを読み出して、構文木に変換する（Ｓ１１１）。次に、変換部１３２は、ノードを格納する変数であるｆｕｎｃｄｉｃと、グラフを格納する変数であるｇｒａｐｈとを初期化する（Ｓ１１２）。例えば、変換部１３２は、ｆｕｎｃｄｉｃ及びｇｒａｐｈを初期化する。
【０１０８】
次に、変換部１３２は、生成した構文木の節点を、グラフ要素に変換する（Ｓ１１３）。変換部１３２は、全ての節点についてグラフ要素に変換するまで処理を繰り返す（Ｓ１１４：Ｎｏ）。変換部１３２は、全ての節点についてグラフ要素に変換すると（Ｓ１１４：Ｙｅｓ）、変換結果である有向グラフを元フローＤＢ１２３に記憶し、Ｓ１２０に移行する。
【０１０９】
図１７に戻って、解決部１３３は、記憶された有向グラフに対して解決処理を行う（Ｓ１２０）。図１９は、実施例１における解決処理の一例を示すフローチャートである。まず、解決部１３３は、有向グラフに含まれる主ノード「λＩ＆」を列挙し（Ｓ１２１）、各主ノードに対して種別「Ｓ」の書換規則を適用する（Ｓ１２２）。解決部１３３は、全ての主ノード「λＩ＆」に対して処理を繰り返す（Ｓ１２３：Ｎｏ）。解決部１３３は、全ての主ノード「λＩ＆」に対処した場合（Ｓ１２３：Ｙｅｓ）、変換結果である有向グラフを解決済みフローＤＢ１２４に記憶し、Ｓ１３０に移行する。
【０１１０】
図１７に戻って、縮約部１３４は、記憶された解決済みの有向グラフに対して縮約処理を行う（Ｓ１３０）。図２０は、実施例１における縮約処理の一例を示すフローチャートである。まず、縮約部１３４は、有向グラフに含まれる主ノード「λＩ＆」を列挙し（Ｓ１３１）、各主ノードに対して種別「Ｄ」の書換規則を適用する（Ｓ１３２）。縮約部１３４は、全ての主ノード「λＩ＆」に対して処理を繰り返す（Ｓ１３３：Ｎｏ）。縮約部１３４は、全ての主ノード「λＩ＆」に対処した場合（Ｓ１３３：Ｙｅｓ）、変換結果である有向グラフを縮約済みフローＤＢ１２６に記憶し、Ｓ１４０に移行する。
【０１１１】
図１７に戻って、解決部１３３は、解決処理及び縮約処理によって有向グラフが更新されたか否かを判定する（Ｓ１４０）。解決部１３３は、有向グラフが更新されたと判定した場合（Ｓ１４０：Ｙｅｓ）、Ｓ１２０に戻って処理を繰り返す。
【０１１２】
解決部１３３は、有向グラフが更新されていないと判定した場合（Ｓ１４０：Ｎｏ）、候補値の入力を受け付けるまで待機する（Ｓ１５０：Ｎｏ）。候補値の入力を受け付けた場合（Ｓ１５０：Ｙｅｓ）、列挙部１３５は、列挙処理を行う（Ｓ１６０）。
【０１１３】
図２１は、実施例１における列挙処理の一例を示すフローチャートである。列挙部１３５は、特定された関数に対して、呼出先のプログラムがあるか否かを判定する（Ｓ１６１）。列挙部１３５は、呼出先のプログラムがないと判定した場合（Ｓ１６１：Ｎｏ）、Ｓ１６２に移行する。一方、列挙部１３５は、呼出先のプログラムがあると判定した場合（Ｓ１６１：Ｙｅｓ）、結合処理を行う（Ｓ１７０）。
【０１１４】
図２２は、実施例１における結合処理の一例を示すフローチャートである。まず、列挙部１３５は、列挙対象とする引数又は変数を含む関数の呼出元を列挙する（Ｓ１７１）。次に、列挙部１３５は、書換規則ＤＢ１２５を参照し、種別「Ｍ」の書換規則を呼出先の有向グラフに適用する（Ｓ１７２）。
【０１１５】
次に、列挙部１３５は、結合した有向グラフに含まれる主ノード「λＩ＆」に対して、種別「Ｍ」の書換規則を適用する（Ｓ１７３）。列挙部１３５は、種別「Ｍ」の書換規則が適用されたグラフに含まれるノード「λＩ＆」に対して、種別「Ｓ」の書換規則を適用する解決処理を行う（Ｓ１７４）。また、列挙部１３５は、ノード「λＩ＆」に対して、種別「Ｄ」の書換規則を適用する解決処理を行う（Ｓ１７５）。
【０１１６】
そして、列挙部１３５は、解決処理及び縮約処理によって結合した有向グラフが更新されたか否かを判定する（Ｓ１７６）。解決部１３３は、結合した有向グラフが更新されたと判定した場合（Ｓ１７６：Ｙｅｓ）、Ｓ１７４に戻って処理を繰り返す。
【０１１７】
列挙部１３５は、結合した有向グラフが更新されていないと判定した場合（Ｓ１７６：Ｎｏ）、列挙した全ての呼出元に対して対処するまで、Ｓ１７２に戻って処理を繰り返す（Ｓ１７７：Ｎｏ）。列挙部１３５は、全ての呼出元に対して対処したと判定した場合（Ｓ１７７：Ｙｅｓ）、Ｓ１６１に戻る。
【０１１８】
図２１に戻って、列挙部１３５は、特定された関数に対して値を設定するノードを列挙する（Ｓ１６２）。次に、列挙部１３５は、有向グラフに含まれるＦノードを、データの流れ及び処理の流れとは逆方向に探索していく（Ｓ１６３）。そして、列挙部１３５は、ＩＶノードに到達するまで探索を繰り返す（Ｓ１６４：Ｎｏ）。
【０１１９】
列挙部１３５は、ＩＶノードに到達すると（Ｓ１６４：Ｙｅｓ）、列挙されたノードを文字列に変換し（Ｓ１６５）、Ｓ１９０に移行する。
【０１２０】
そして、出力部１３６は、値候補ＤＢ１２７に記憶された引数又は変数の候補値を、通信部１１０を通じて出力し（Ｓ１９０）、処理を終了する。
【０１２１】
［効果］
以上説明したように、本実施例における解析方法は、コンピュータが、プログラムの関数内のデータの流れと処理の流れとを表現する有向グラフを生成する。解析方法は、コンピュータが、データの流れと処理の流れとを用いて、動的型の参照解決と名前解決を実行する。解析方法は、コンピュータが、有向グラフをプログラムの関数単位で縮約する。さらに、解析方法は、コンピュータが、縮約した結果のうち、解析指示を受けた関数に関する解決結果を合わせた後に、データの処理の流れを探索する。これにより、動的型付き言語のソースコードを解析する際の誤列挙及び列挙漏れを抑制できる。
【０１２２】
また、解析方法は、コンピュータが、処理に対応する第１ノードと、データの参照に対応する第２ノードと、データの設定に対応する第３ノードとの接続関係を示す３部グラフを生成する。また、解析方法は、コンピュータが、第２ノード及び第３ノードとして、環境を渡すノードを含む３部グラフを生成する。これにより、データの流れ及び処理の流れを容易に特定できる。
【０１２３】
また、解析方法は、コンピュータが、有向グラフを、解析指示を受けた関数の呼出先となるソースコードから生成された有向グラフの一部又は全部と結合し、結合された新たな有向グラフを用いてデータの処理の流れを探索する。これにより、呼出関係にあるその他のソースコードも含めて、データの流れ及び処理の流れを特定できる。
【０１２４】
また、解析方法は、コンピュータが、探索された、関数に渡される値の候補を出力するので、候補値を容易に知得できる。
【０１２５】
また、解析方法は、コンピュータが、関数の呼出し時に参照されるオブジェクトの設定値候補を列挙することにより、関数が所属するクラスを特定する。これにより、誤列挙及び列挙漏れなく、候補値を列挙できる。
【０１２６】
さらに、解析方法は、コンピュータが、有向グラフのうち、設定値候補の列挙対象の変数・引数が現れる関数に関連する部分に探索範囲を限定してデータの流れをたどるので、解析の時間を短縮できる。
【実施例２】
【０１２７】
さて、これまで本発明の実施例について説明したが、本発明は上述した実施例以外にも、種々の異なる形態にて実施されてよいものである。例えば、実施例１に示す解析装置１００は、プログラムに含まれる関数の引数の値を列挙することに加え、実施例１と同様の機能ブロックを用いて、実施例１と同様の処理の流れにより、関数内の変数への設定値を列挙することもできる。そこで、解析装置１００が関数内の変数への設定値を列挙する構成について説明する。
【０１２８】
本実施例において解析対象とするソースコードを、図２３及び図２４を用いて説明する。図２３は、実施例２におけるソースコード変換結果の一例を示す図である。符号４０００に示すソースコード４は、引数「ｓｅｌｆ」及び「ｎ」に対して、戻り値「ｎ」を返す関数「Ｃａｌｃ．ａｂｓ」を定義するクラス「Ｃａｌｃ」のソースコードである。
【０１２９】
図２４は、実施例２におけるソースコード変換結果の別の一例を示す図である。符号５０００に示すソースコード５は、引数「ｓｅｌｆ」及び「ｘ」に対して、「ｓｅｌｆ．ｎ」を戻り値として返す関数「Ｃａｌｃ．ｇｅｔ」を定義するクラス「Ｃａｌｃ」のソースコードである。本実施例においては、関数「Ｃａｌｃ．ｇｅｔ」において、変数「ｎ」に設定される値の候補値を列挙する例について説明する。
【０１３０】
図２４に示すように、関数「Ｃａｌｃ．ｇｅｔ」は、ソースコード４に含まれる関数「Ｃａｌｃ．ａｂｓ」を呼び出している。そこで、解析装置１００は、ソースコード５から有向グラフ５１００を生成し、ソースコード４から生成した有向グラフ４１００と統合する。
【０１３１】
図２５Ａ及び図２５Ｂは、ソースコード５の列挙処理及び統合処理の一例を示す図である。図２５Ａに示すように、解析装置１００の列挙部１３５は、有向グラフ４１００と有向グラフ５１００とを統合した有向グラフ８１００に対して、種別「Ｍ」の書換規則「ＡＣ＿Ｅ」を適用することにより、有向グラフ８２００を生成する。
【０１３２】
次に、列挙部１３５は、変数「ｎ」に関するノード「ＷＭ」８２０１に対して、変数「ｎ」に関するパラメータを受け渡すノードとして、ノード「ＩＤ」８２１１及びノード「ＩＤ」８２２１を列挙する。
【０１３３】
図２５Ｂに移って、列挙部１３５は、ノード「ＩＤ」８２１１に対して変数「ｎ」に関するパラメータを受け渡すノードとして、ノード「λＩ＆」８２３１を列挙する。また、列挙部１３５は、ノード「ＩＤ」８２２１に対して変数「ｎ」に関するパラメータを受け渡すノードとして、ノード「Ｆ」８２２２を列挙する。さらに、列挙部１３５は、ノード「Ｆ」８２２２に対して変数「ｎ」に関するパラメータを受け渡すノードとして、ノード「λＩ＆」８２３１を列挙する。
【０１３４】
そして、列挙部１３５は、列挙されたノードを用いて、変数「ｎ」に設定される値の候補値を生成する。列挙部１３５は、ノード「ＩＤ」８２１１に対応する値「λＩ＆Ｃａｌｃ．ｇｅｔ．３」８９１１を、候補値として列挙する。また、列挙部１３５は、ノード「ＩＤ」８２２１に対応する値「Ｆ  −  λＩ＆Ｃａｌｃ．ｇｅｔ．３」８９２１を、候補値として列挙する。
【０１３５】
そして、出力部１３６は、列挙された候補値を含む出力画面８９９９を、例えば通信部１１０を通じて利用者の端末に出力する。
【０１３６】
このように、解析装置１００は、プログラムに含まれる関数内の変数への設定値を列挙することもできる。
【０１３７】
［システム］
また、図示した各部の各構成要素は、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各部の分散・統合の具体的形態は図示のものに限られず、その全部または一部を、各種の負荷や使用状況等に応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。例えば、解決部１３３と縮約部１３４とを統合してもよい。また、図示した各処理は、上記の順番に限定されるものではなく、処理内容を矛盾させない範囲において、同時に実施してもよく、順序を入れ替えて実施してもよい。
【０１３８】
さらに、各装置で行われる各種処理機能は、ＣＰＵ（又はＭＰＵ、ＭＣＵ（Micro  Controller  Unit）等のマイクロ・コンピュータ）上で、その全部または任意の一部を実行するようにしてもよい。また、各種処理機能は、ＣＰＵ（またはＭＰＵ、ＭＣＵ等のマイクロ・コンピュータ）で解析実行されるプログラム上、またはワイヤードロジックによるハードウェア上で、その全部又は任意の一部を実行するようにしてもよいことは言うまでもない。  
【０１３９】
ところで、上記の各実施例で説明した各種の処理は、予め用意されたプログラムをコンピュータで実行することで実現できる。そこで、以下では、上記の各実施例と同様の機能を有するプログラムを実行するコンピュータの一例を説明する。図２６は、解析プログラムを実行するコンピュータの一例を示す図である。
【０１４０】
図２６に示すように、コンピュータ３００は、各種演算処理を実行するＣＰＵ３７０と、データ入力を受け付ける入力装置３１０と、出力装置３２０とを有する。また、コンピュータ３００は、記憶媒体からプログラム等を読み取る媒体読取装置３４０と、各種装置との間でデータの授受を行う通信インターフェース（ＩＦ）３３０とを有する。また、コンピュータ３００は、各種情報を一時記憶するＲＡＭ３６０と、ハードディスク装置（ＨＤＤ）３５０とを有する。また、各装置３１０〜３７０は、バス３８０に接続される。
【０１４１】
ＨＤＤ３５０には、図４に示した取得部１３１、変換部１３２、解決部１３３、縮約部１３４、列挙部１３５及び出力部１３６の各処理部と同様の機能を有する解析プログラム３５１が記憶される。また、ＨＤＤ３５０には、ソースコードＤＢ１２１、クラス定義ＤＢ１２２、元フローＤＢ１２３、解決済みフローＤＢ１２４、書換規則ＤＢ１２５、縮約済みフローＤＢ１２６及び値候補ＤＢ１２７が記憶される。さらに、ＨＤＤ３５０には、解析プログラム３５１を実現するための各種データが記憶される。入力装置３１０は、例えば、コンピュータ３００の管理者から各種情報の入力を受け付ける。出力装置３２０は、例えば、コンピュータ３００の管理者に対して各種画面を表示する。通信ＩＦ３３０は、図示しないネットワークと接続され、各種装置と各種情報をやりとりする。    
【０１４２】
ＣＰＵ３７０は、ＨＤＤ３５０に記憶された解析プログラム３５１などの各プログラムを読み出して、ＲＡＭ３６０に展開して実行することで、解析プロセス３７１を行う。また、これらのプログラムは、コンピュータ３００を図４に示した取得部１３１、変換部１３２、解決部１３３、縮約部１３４、列挙部１３５及び出力部１３６として機能させることができる。    
【０１４３】
なお、上記の解析プログラム３５１は、必ずしもＨＤＤ３５０に記憶されている必要はない。例えば、コンピュータ３００が読み取り可能な記憶媒体に記憶されたプログラムを、コンピュータ３００が読み出して実行するようにしてもよい。コンピュータ３００が読み取り可能な記憶媒体は、例えば、ＣＤ−ＲＯＭやＤＶＤ（Digital  Versatile  Disk）、ＵＳＢ（Universal  Serial  Bus）メモリ等の可搬型記録媒体、フラッシュメモリ等の半導体メモリ、ハードディスクドライブ等が対応する。また、公衆回線、インターネット、ＬＡＮ等に接続された装置にこの解析プログラムを記憶させておき、コンピュータ３００がこれらから解析プログラムを読み出して実行するようにしてもよい。
【符号の説明】
【０１４４】
１００  解析装置
１１０  通信部
１２０  記憶部
１２１  ソースコードＤＢ
１２２  クラス定義ＤＢ
１２３  元フローＤＢ
１２４  解決済みフローＤＢ
１２５  書換規則ＤＢ
１２６  縮約済みフローＤＢ
１２７  値候補ＤＢ
１３０  制御部
１３１  取得部
１３２  変換部
１３３  解決部
１３４  縮約部
１３５  列挙部
１３６  出力部
【図１】
2019061587.tif 000003
【図２】
2019061587.tif 000004
【図３】
2019061587.tif 000005
【図４】
2019061587.tif 000006
【図５】
2019061587.tif 000007
【図６】
2019061587.tif 000008
【図７】
2019061587.tif 000009
【図８】
2019061587.tif 000010
【図９】
2019061587.tif 000011
【図１０】
2019061587.tif 000012
【図１１】
2019061587.tif 000013
【図１２】
2019061587.tif 000014
【図１３】
2019061587.tif 000015
【図１４】
2019061587.tif 000016
【図１５Ａ】
2019061587.tif 000017
【図１５Ｂ】
2019061587.tif 000018
【図１５Ｃ】
2019061587.tif 000019
【図１５Ｄ】
2019061587.tif 000020
【図１５Ｅ】
2019061587.tif 000021
【図１５Ｆ】
2019061587.tif 000022
【図１６Ａ】
2019061587.tif 000023
【図１６Ｂ】
2019061587.tif 000024
【図１６Ｃ】
2019061587.tif 000025
【図１６Ｄ】
2019061587.tif 000026
【図１６Ｅ】
2019061587.tif 000027
【図１６Ｆ】
2019061587.tif 000028
【図１６Ｇ】
2019061587.tif 000029
【図１７】
2019061587.tif 000030
【図１８】
2019061587.tif 000031
【図１９】
2019061587.tif 000032
【図２０】
2019061587.tif 000033
【図２１】
2019061587.tif 000034
【図２２】
2019061587.tif 000035
【図２３】
2019061587.tif 000036
【図２４】
2019061587.tif 000037
【図２５Ａ】
2019061587.tif 000038
【図２５Ｂ】
2019061587.tif 000039
【図２６】
2019061587.tif 000040