(57)【要約】【課題】解析対象を解析して、開発者が意図しない命令文の依存関係を検出すること。【解決手段】呼び出し先となる第１の命令文と、呼び出し先と呼び出し元との依存関係を規定するフィルタルールおよび呼び出し元となる第２の命令文の組み合わせであるアノテーション属性と、を対応付けた対応情報を記憶する記憶デバイスにアクセス可能なプロセッサが、アノテーション属性を含む解析対象から、第２の命令文を検出する検出処理と、対応情報を参照して、第２の命令文と第２の命令文によって呼び出される呼び出し先の命令文が、検出処理によって検出された第２の命令文を呼び出し元とするフィルタルールに適合するか否かを判定する判定処理と、判定処理によって適合すると判定された判定結果に関する情報を生成する生成処理と、生成処理によって生成された判定結果に関する情報を出力する出力処理と、を実行する。【選択図】図１
2016122321.tif 000002
【特許請求の範囲】
【請求項１】
プロセッサと、前記プロセッサにより実行されるプログラムを記憶する記憶デバイスと、を有する解析装置であって、
前記記憶デバイスは、呼び出し先となる第１の命令文と、呼び出し先と呼び出し元との依存関係を規定するフィルタルールおよび呼び出し元となる第２の命令文の組み合わせであるアノテーション属性と、を対応付けた対応情報を記憶し、
前記プロセッサは、
プログラムリスト、中間ファイル、またはプログラムのいずれかであり、かつ、前記アノテーション属性を含む解析対象から、前記第２の命令文を検出する検出処理と、
前記検出処理によって検出された前記第２の命令文と当該第２の命令文によって呼び出される呼び出し先の命令文との依存関係が、前記フィルタルールに適合するか否かを、前記対応情報を参照して判定する判定処理と、
前記判定処理によって適合すると判定された判定結果に関する情報を生成する生成処理と、
前記生成処理によって生成された判定結果に関する情報を出力する出力処理と、
を実行することを特徴とする解析装置。
【請求項２】
前記フィルタルールは、前記第２の命令文が前記アノテーション属性に対応する前記第１の命令文以外の他の命令文の呼び出しを呼び出し違反として検出するフィルタルールであり、
前記判定処理では、前記プロセッサは、前記呼び出し先の命令文が前記第１の命令文でない場合、前記呼び出し違反を検出したことにより、前記フィルタルールに適合すると判定することを特徴とする請求項１に記載の解析装置。
【請求項３】
前記生成処理では、前記プロセッサは、前記フィルタルールに適合すると判定された場合、前記判定結果に関する情報として、前記第１の命令文が前記第２の命令文から呼び出されていることを示す情報を生成することを特徴とする請求項２に記載の解析装置。
【請求項４】
前記生成処理では、前記プロセッサは、前記フィルタルールに適合すると判定された場合、前記呼び出し先の命令文を、前記第１の命令文に置換することを特徴とする請求項２に記載の解析装置。
【請求項５】
前記フィルタルールは、前記アノテーション属性に対応する前記第１の命令文に関する属性が前記第２の命令文にも波及することを検出するフィルタルールであり、
前記判定処理では、前記プロセッサは、前記呼び出し先の命令文が前記第１の命令文である場合、前記波及を検出したことにより、前記フィルタルールに適合すると判定することを特徴とする請求項１に記載の解析装置。
【請求項６】
前記生成処理では、前記プロセッサは、前記フィルタルールに適合すると判定された場合、前記判定結果に関する情報として、前記第１の命令文に関する属性が前記第２の命令文にも波及することを示す情報を生成することを特徴とする請求項５に記載の解析装置。
【請求項７】
前記プロセッサは、
前記解析対象が前記プログラムリストである場合、前記プログラムリストを構文解析する構文解析処理を実行し、
前記検出処理では、前記プロセッサは、前記構文解析処理の実行により得られる前記プログラムリストの構文解析木を用いて、前記プログラムリストから前記第２の命令文を検出することを特徴とする請求項１に記載の解析装置。
【請求項８】
前記プロセッサは、
前記解析対象が前記プログラムリストである場合、前記プログラムリストから、呼び出し先となる第１の命令文と前記アノテーション属性とを取得して、前記第１の命令文と前記アノテーション属性とを対応付けた前記対応情報を前記記憶デバイスに格納する格納処理を実行することを特徴とする請求項１に記載の解析装置。
【請求項９】
前記プロセッサは、
前記解析対象が中間ファイルである場合、前記中間ファイルから未取得の行を取得する取得処理と、
前記取得処理によって取得された行がニーモニックであるか否かを判断する判断処理と、を実行し、
前記検出処理では、前記プロセッサは、前記判断処理によってニーモニックであると判断された行から、前記第２の命令文を検出し、
前記取得処理では、前記プロセッサは、前記判断処理によってニーモニックでないと判断された場合、前記中間ファイルから未取得の行を再取得することを特徴とする請求項１に記載の解析装置。
【請求項１０】
プロセッサと、前記プロセッサにより実行されるプログラムを記憶する記憶デバイスと、を有する解析装置による解析方法であって、
前記記憶デバイスは、呼び出し先となる第１の命令文と、呼び出し先と呼び出し元との依存関係を規定するフィルタルールおよび呼び出し元となる第２の命令文の組み合わせであるアノテーション属性と、を対応付けた対応情報を記憶し、
前記解析方法は、
前記プロセッサが、
プログラムリスト、中間ファイル、またはプログラムのいずれかであり、かつ、前記アノテーション属性を含む解析対象から、前記第２の命令文を検出する検出処理と、
前記検出処理によって検出された前記第２の命令文と当該第２の命令文によって呼び出される呼び出し先の命令文との依存関係が、前記フィルタルールに適合するか否かを、前記対応情報を参照して判定する判定処理と、
前記判定処理によって適合すると判定された判定結果に関する情報を生成する生成処理と、
前記生成処理によって生成された判定結果に関する情報を出力する出力処理と、
を実行することを特徴とする解析方法。
【請求項１１】
前記フィルタルールは、前記第２の命令文が前記アノテーション属性に対応する前記第１の命令文以外の他の命令文の呼び出しを呼び出し違反として検出するフィルタルールであり、
前記判定処理では、前記プロセッサは、前記呼び出し先の命令文が前記第１の命令文でない場合、前記呼び出し違反を検出したことにより、前記フィルタルールに適合すると判定することを特徴とする請求項１０に記載の解析方法。
【請求項１２】
前記フィルタルールは、前記アノテーション属性に対応する前記第１の命令文に関する属性が前記第２の命令文にも波及することを検出するフィルタルールであり、
前記判定処理では、前記プロセッサは、前記呼び出し先の命令文が前記第１の命令文である場合、前記波及を検出したことにより、前記フィルタルールに適合すると判定することを特徴とする請求項１０に記載の解析方法。
【請求項１３】
呼び出し先となる第１の命令文と、呼び出し先と呼び出し元との依存関係を規定するフィルタルールおよび呼び出し元となる第２の命令文の組み合わせであるアノテーション属性と、を対応付けた対応情報を記憶する記憶デバイスにアクセス可能なプロセッサに、
プログラムリスト、中間ファイル、またはプログラムのいずれかであり、かつ、前記アノテーション属性を含む解析対象から、前記第２の命令文を検出する検出処理と、
前記検出処理によって検出された前記第２の命令文と当該第２の命令文によって呼び出される呼び出し先の命令文との依存関係が、前記フィルタルールに適合するか否かを、前記対応情報を参照して判定する判定処理と、
前記判定処理によって適合すると判定された判定結果に関する情報を生成する生成処理と、
前記生成処理によって生成された判定結果に関する情報を出力する出力処理と、
を実行させることを特徴とする解析プログラム。
【請求項１４】
前記フィルタルールは、前記第２の命令文が前記アノテーション属性に対応する前記第１の命令文以外の他の命令文の呼び出しを呼び出し違反として検出するフィルタルールであり、
前記判定処理では、前記プロセッサに、前記呼び出し先の命令文が前記第１の命令文でない場合、前記呼び出し違反を検出したことにより、前記フィルタルールに適合すると判定させることを特徴とする請求項１３に記載の解析プログラム。
【請求項１５】
前記フィルタルールは、前記アノテーション属性に対応する前記第１の命令文に関する属性が前記第２の命令文にも波及することを検出するフィルタルールであり、
前記判定処理では、前記プロセッサに、前記呼び出し先の命令文が前記第１の命令文である場合、前記波及を検出したことにより、前記フィルタルールに適合すると判定させることを特徴とする請求項１３に記載の解析プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラムリスト、中間ファイル、またはプログラムのいずれかである解析対象を解析する解析装置、解析方法、および解析プログラムに関する。
【背景技術】
【０００２】
インターネット等のオープンネットワークには、オープンソースソフトウェア（ＯＳＳ）と呼ばれるプログラムリスト付きのソフトウェアが公開されている。ＯＳＳのプログラムリストについては、開発者が開発するプログラムリストに自由に組み込むことが可能である。ＯＳＳには、ライセンスが指定されていることがあり、例えば、ＯＳＳには、ＧＮＵ  Ｐｕｂｌｉｃ  Ｌｉｃｅｎｓｅ（以下、ＧＰＬ）と呼ばれるライセンスが存在する。ＧＰＬには、ＧＰＬのファイルを取り込んだファイルはＧＰＬとして配布されなければならないという条項が記載されている。
【０００３】
ＧＰＬにはソースコード開示義務が存在するため、プロプライエタリなソフトウェアを開発する際に、ＧＰＬのファイルを取り込むことにより、意図しないソースコード開示義務が発生することがある。また、ＧＰＬが指定されたＯＳＳだけではなく、このＯＳＳを取り込んだプログラムに対してもＧＰＬが適用される。したがって、当該プログラムについてＧＰＬの条項と違う使い方をすると、ライセンス違反になる。
【０００４】
したがって、ファイル間において呼び出し元と呼び出し先の関係を示す依存関係を抽出して、開発者がどんなＯＳＳを取り込んで、そのＯＳＳにどんなライセンスが設定されているかを解析する必要がある。
【０００５】
背景技術として、プログラムリストのファイル依存関係を抽出するシステムがある（下記特許文献１を参照）。当該システムは、ビルド情報やプログラムリストの文字列を判定し、プログラムリストの関数呼び出し等におけるプログラムリスト相互間の依存関係を判定する。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２００８−２９３４８６号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
特許文献１のシステムは、関数の特定の呼び出し関係において、開発者が意図しない呼び出しに対する警告を行うことができない。また、特許文献１のシステムは、プログラムリスト、中間ファイル、プログラム等、プログラム開発における全てのファイルに対して依存関係を取得するものではない。
【０００８】
また、特許文献１のシステムは、実行時に命令文が追加、削除等の変更を行うアルゴリズムが記載されたプログラムリストには対応できない。例えば、プログラムリスト上に命令文が記載されているプログラム上の命令文を参照するためのアドレスしか記載されず、命令文を参照するプログラムがある場合、実行時にアドレスが示す先の命令文を変更することでプログラムの挙動を変更することが可能になる。したがって、当該プログラムでは、プログラムリストを検査してもアドレスの値、例えば数値しか取得できない場合、アルゴリズムを記載する命令文は検査できないことになる。
【０００９】
また、アドレスが指し示す先の命令文を検査するための装置および方法を実施したとしても、命令文の追加、削除等の変更の有無を検出するにすぎず、開発者が開発するプログラムリストに対して命令文の変更が、開発者が新たに開発したアルゴリズムによる命令文の変更か、開発者の意図しないアルゴリズムによる命令文の変更かを区別することはできない。
【００１０】
さらに、呼び出し関係におけるファイル間の属性の波及によるファイル相互の影響を判定することができないため、呼び出し関係によっては問題となるライセンス伝播や脆弱性のような検査として用いることができない。
【００１１】
本発明は、プログラムリスト、中間ファイル、またはプログラムのいずれかである解析対象を解析して、開発者が意図しない命令文の依存関係を検出することを目的とする。
【００１２】
本発明は、
【課題を解決するための手段】
【００１３】
本願において開示される発明の一側面となる解析装置は、プロセッサと、前記プロセッサにより実行されるプログラムを記憶する記憶デバイスと、を有し、前記記憶デバイスは、呼び出し先となる第１の命令文と、呼び出し先と呼び出し元との依存関係を規定するフィルタルールおよび呼び出し元となる第２の命令文の組み合わせであるアノテーション属性と、を対応付けた対応情報を記憶し、前記プロセッサは、プログラムリスト、中間ファイル、またはプログラムのいずれかであり、かつ、前記アノテーション属性を含む解析対象から、前記第２の命令文を検出する検出処理と、前記検出処理によって検出された前記第２の命令文と当該第２の命令文によって呼び出される呼び出し先の命令文との依存関係が、前記フィルタルールに適合するか否かを、前記対応情報を参照して判定する判定処理と、前記判定処理によって適合すると判定された判定結果に関する情報を生成する生成処理と、前記生成処理によって生成された判定結果に関する情報を出力する出力処理と、を実行することを特徴とする。
【発明の効果】
【００１４】
本発明の代表的な実施の形態によれば、プログラムリスト、中間ファイル、またはプログラムのいずれかである解析対象を解析して、開発者が意図しない命令文の依存関係を検出することができる。前述した以外の課題、構成及び効果は、以下の実施例の説明により明らかにされる。
【図面の簡単な説明】
【００１５】
【図１】本実施例に係る解析対象の解析例を示す説明図である。
【図２】解析対象間の呼び出しの依存関係例１を示す説明図である。
【図３】解析対象間の呼び出しの依存関係例２を示す説明図である。
【図４】図２および図３に示したプログラムリストの記述例を示す説明図である。
【図５】図２および図３に示した中間ファイルの記述例を示す説明図である。
【図６】解析結果例および警告例（その１）を示す説明図である。
【図７】解析結果例および警告例（その２）を示す説明図である。
【図８】解析結果例および警告例（その３）を示す説明図である。
【図９】解析装置のハードウェア構成例を示すブロック図である。
【図１０】命令文情報格納テーブルの記憶内容例を示す説明図である。
【図１１】インターフェース情報格納テーブルの記憶内容例を示す説明図である。
【図１２】プログラム情報格納テーブルの記憶内容例を示す説明図である。
【図１３】フィルタルール情報格納テーブルの記憶内容例を示す説明図である。
【図１４】解析装置の機能的構成例を示すブロック図である。
【図１５】解析装置の構文解析で取得される構文解析木の例を示す説明図である。
【図１６】構文解析部による構文解析処理例を示すフローチャートである。
【図１７】ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）の詳細な処理手順例を示すフローチャートである。
【図１８】構文解析木による依存関係抽出処理（ステップＳ１８００）の詳細な処理手順例（前半）を示すフローチャートである。
【図１９】構文解析木による依存関係抽出処理（ステップＳ１８００）の詳細な処理手順例（後半）を示すフローチャートである。
【図２０】生成部による解析処理例を示すフローチャートである。
【図２１】図２０に示した依存関係抽出処理（ステップＳ２００６）の詳細な処理手順例を示すフローチャート１である。
【図２２】図２０に示した依存関係抽出処理（ステップＳ２００６）の詳細な処理手順例を示すフローチャート２である。
【図２３】図２０に示した依存関係抽出処理（ステップＳ２００６）の詳細な処理手順例を示すフローチャート３である。
【図２４】実行部による解析処理の詳細な処理手順例を示すフローチャートである。
【図２５】図２４に示した依存関係抽出処理（ステップＳ２４０６）の詳細な処理手順例を示すフローチャート１である。
【図２６】図２４に示した依存関係抽出処理（ステップＳ２４０６）の詳細な処理手順例を示すフローチャート２である。
【図２７】図２４に示した依存関係抽出処理（ステップＳ２４０６）の詳細な処理手順例を示すフローチャート３である。
【図２８】メモリマップの一例を示す説明図である。
【図２９】シンボルテーブルの一例を示す説明図である。
【発明を実施するための形態】
【００１６】
本実施例は、プログラムリスト、中間ファイル、またはプログラム等、プログラム開発における解析対象（単に、「ファイル」と称する場合がある）について呼び出し元と呼び出し先の関係を示す依存関係を抽出して、開発者がどんなＯＳＳを取り込んで、そのＯＳＳにどんなライセンスが設定されているかを解析する。
【００１７】
＜解析例＞
図１は、本実施例に係る解析対象の解析例を示す説明図である。図１では、解析対象の一例としてプログラムリストを用いて説明する。（Ａ）は、解析対象であるプログラムリストの一例を示す。（Ｂ）は、解析対象についての解析結果例を示す。（Ｃ）は、解析対象に対する警告情報例を示す。
【００１８】
プログラムリストにおいて、１行目にはアノテーション１０（［［ｍａｔｈ］）が記述されている。アノテーション１０は、当該アノテーション１０が挿入されている行の関数１４（例としてａｄｄ）に対する注釈である。したがって、関数１４（ａｄｄ）が出現した場合には、（Ｂ）の解析においてアノテーション１０が適用される。
【００１９】
アノテーション１０の左端のカッコ１１ａおよび右端のカッコ１１ｂは、アノテーション１０の開始と終了を規定する記号である。記号１２は、フィルタルールに対応する記号である。関数１３は、フィルタルールにしたがって関数１４との依存関係が規定される関数である。記号１２と関数１３との組み合わせにより、アノテーション１０に適用される属性（以下、アノテーション属性）が定義される。
【００２０】
フィルタルールは、記号１２と関数１３との組み合わせにより規定されるアノテーション属性に応じて規定される関数である。たとえば、図１に示したフィルタルールＡ１（）は、『ｍａｔｈ（関数１３）が特定の関数（この場合は例としてａｄｄ（関数１４））を呼び出す場合は呼び出し遵守となり、それ以外の関数から呼び出される場合は呼び出し違反となる』ことを規定する関数である。フィルタルールが、直接ライセンスの遵守または違反を規定する場合には、呼び出し遵守がライセンス遵守となり、呼び出し違反がライセンス違反となる。
【００２１】
（Ｂ）は、（Ａ）のプログラムリストの解析結果画面１０２である。解析結果画面１０２には、解析結果１２０が表示される。解析結果１２０では、例としてプログラムリスト内の関数群をツリー構造（コールグラフ）で表現する。解析箇所１２１は、記述箇所１１１の解析結果である。関数１４（ａｄｄ）は、関数１３（ｍａｔｈ）から呼び出されている。したがって、フィルタルールＡ１（）が適用されると、呼び出し遵守と判定される。一方、解析箇所１２２は、記述箇所１１２の解析結果である。関数１４（ａｄｄ）は、関数（ｈｉｓｔｏｒｙ）から呼び出されている。したがって、フィルタルールＡ１（）が適用されると、属性違反と判定される。
【００２２】
（Ｃ）は、（Ｂ）の解析結果からの警告画面１０３である。解析箇所１２２が属性違反と判定されるため、その旨の内容を示す文字列である警告情報１３０を有する警告画面１０３が出力される。このように、プログラムリスト１０１の作成時にアノテーション１０を挿入しておくことで、属性違反となる箇所を特定することができる。
【００２３】
＜依存関係例＞
図２は、解析対象間の呼び出しの依存関係例１を示す説明図である。中間ファイルはプログラムリストから生成され、プログラムは中間ファイルから生成される。プログラムリスト２０１〜２０３は、例えば、入力デバイスを用いて開発者が命令文を記載するファイルとする。プログラムリスト２０１〜２０３に記載される命令文は、例えば、構文解析処理、コード生成処理等が実行されるコンパイル処理２０９〜２１１により、命令文のアルゴリズムが変更されることなく、コンピュータが実行する命令文に変換される。
【００２４】
コンパイル処理２０９〜２１１により、中間ファイル２０４〜２０６が生成される。つぎに、例えばコード生成処理や参照等が実行されるリンク処理２１２〜２１５により、複数に分けられたファイルの命令文を纏める処理が行われ、中間ファイル２０４および中間ファイル２０５からプログラム２０７が生成される。また、中間ファイル２０６からプログラム２０８が生成される。リンク処理２１２，２１３は、例えば、中間ファイル２０４と中間ファイル２０５とを結合してプログラム２０７を生成するスタティックリンク処理を指す。スタティックリンク処理では、複数に分かれたファイルが一つのファイルとして結合される。リンク処理２１４は、例えば、中間ファイル２０６からプログラム２０８を生成するスタティックリンク処理を指す。リンク処理２１５は、例えば、プログラム２０８の起動時または実行中に、プログラム２０８と中間ファイル２０６を結合するダイナミックリンク処理を指す。
【００２５】
なお、図２において、プログラムリスト２０１〜２０３、中間ファイル２０４〜２０６、およびプログラム２０７を図示する際に、ファイル名に拡張子（「.（ドット）」以降の文字列）を記載しているが、拡張子はどのような文字列でもよく、また、拡張子はなくてもよく、解析対象のフォーマットは任意の形式でよい。さらに、また、プログラムリスト２０１〜２０３、中間ファイル２０４〜２０６、およびプログラム２０７に記載された命令文は必ずしも人間に対して可読なデータでなくてもよい。
【００２６】
図２におけるプログラムリスト２０１〜２０３、中間ファイル２０４〜２０６、およびプログラム２０７の相互依存関係は、コンパイル処理２０９〜２１１やリンク処理２１２〜２１４による依存関係の一例であり、開発者はコンパイル処理２０９〜２１１やリンク処理２１２〜２１４の一部または全部を省いてもよい。さらに、中間ファイル２０４〜２０６やプログラム２０７の命令文を開発者が入力デバイスによって直接記述して中間ファイル２０４〜２０６やプログラム２０７を作成してもよい。
【００２７】
なお、コンパイル処理の前後には、プリプロセス処理やアセンブル処理等が実行されることもある。また、プリプロセス処理、アセンブル処理、コンパイル処理２０９〜２１１、リンク処理２１２〜２１４等は、それぞれが別々のプログラムとして実装されていることもあれば、同一のプログラムの処理実装されることもある。プリプロセス処理、アセンブル処理、コンパイル処理２０９〜２１１、リンク処理２１２〜２１４等の実装の差異によるプログラムを生成する処理の過程の違いは、本実施例の技術を実施する際の実装をプリプロセス処理、アセンブル処理、コンパイル処理２０９〜２１１、リンク処理２１２〜２１４等の実装に合わせることで吸収することが可能である。
【００２８】
図３は、解析対象間の呼び出しの依存関係例２を示す説明図である。図３は、プログラムが呼び出すプログラムの依存関係が、プログラムの実行中に判明する場合のプログラムの実行例である。図３のプログラム３０１「ｍａｉｎ２.ｅｘｅ」は、例えば、プログラム３０１に記載されたアルゴリズム３１１の命令文３１２により、インターネット３０５、及びインターネット３０７を介し、Ｗｅｂ３０６よりプログラムリスト３０２「ｅｎｇｌｉｓｈ.ｃ」をダウンロードする。なお、アルゴリズム３１１は、例として可読なデータとしたが、実際には機械語等で実装されているものとする。また、命令文３１２は、例えば、特定のＷｅｂに記載されたファイルをダウンロードする処理として、ダウンロードするファイルを選択する処理は行わないとする。
【００２９】
つぎに、命令文３１３により、ダウンロードしたファイルから中間ファイル３０３「ｅｎｇｌｉｓｈ.ｏｂｊ」を、例えば、コンパイル処理３０８により生成し、中間ファイル３０３からプログラム３０４を、例えば、リンク処理３０９により生成する。つぎに、例えば、命令文３１４によるロード処理３１０により、プログラム３０４をプログラム３０１に読み込み結合する。コンパイル処理３０８では、構文解析処理やコード生成処理等が実行される。リンク処理３０９では、コード生成処理等が実行される。ロード処理３１０では、例えば、ローダ、ダイナミックリンカ等によってプログラムに記載された命令文の読み込み処理が行われ、プログラムの実行中にプログラム相互の命令文を結合する処理が実行される。なお、図３において、プログラムリスト３０２、中間ファイル３０３、およびプログラム３０１を図示する際に、ファイル名に拡張子（「.（ドット）」以降の文字列）を記載しているが、発明の実施にあたり拡張子はどのような文字列でもよく、また、拡張子はなくてもよく、ファイルのフォーマットは任意の形式でよい。
【００３０】
また、図２および図３において、プログラムを開発または実行する環境において、ＯＳ、ＣＰＵ、メモリ、ストレージ等は、任意の構成でよい。開発者は、開発者が構築する任意の環境で動作するプログラムを開発するが、クロスプラットフォームでの開発環境や、開発環境が別のコンピュータである場合、必ずしも開発環境の構成が、プログラムの動作条件に適合していなくともよい。尚、本実施例は開発環境に依存する技術ではないため、プログラムの動作条件による開発環境の違いには依存せずに、本技術を実施することが可能である。
【００３１】
＜解析対象の記述例＞
図４は、図２および図３に示したプログラムリスト２０１〜２０３、３０２の記述例を示す説明図である。プログラムリスト２０１には、開発者が関数を記載する際のアルゴリズムとして、関数定義４０２、関数定義４０５、関数定義４０８、および関数定義４１１が記載されている。関数定義４０２は、関数４０４「ａｄｄ」の処理と、関数４０４に対して付与される属性４０３「［［ｍａｔｈ］」がアノテーションとして記載されている。アノテーションについては、図１に説明した通りである。
【００３２】
関数定義４０５には、関数４０６「ｍａｔｈ」が関数４０７「ａｄｄ」を呼び出すための命令文が記載されている。関数定義４０８には、関数４０９「ｈｉｓｔｏｒｙ」が関数４１０「ａｄｄ」を呼び出すための命令文が記載されている。関数定義４１１には、関数４１２「ｍａｉｎ」が関数４１３「ｍａｔｈ」、関数４１４「ｈｉｓｔｏｒｙ」、関数４１５「ｓｃｉｅｎｃｅ」、および関数４１６「ｇｅｏｇｒａｐｈｙ」を呼び出すための命令文が記載されている。
【００３３】
また、プログラムリスト２０２「ｓｃｉｅｎｃｅ.ｃ」には、開発者が関数を記載する際のアルゴリズムとして、関数定義４１８が記載されている。関数定義４１８には、関数４１９「ｓｃｉｅｎｃｅ」が関数４２０「ａｄｄ」を呼び出すための命令文が記載されている。
【００３４】
また、プログラムリスト２０３「ｇｅｏｇｒａｐｈｙ.ｃ」には、開発者が関数を記載する際のアルゴリズムとして、関数定義４２２が記載されている。関数定義４２２には、関数４２３「ｇｅｏｇｒａｐｈｙ」が関数４２４「ａｄｄ」を呼び出すための命令文が記載されている。
【００３５】
また、プログラムリスト３０２「ｅｎｇｌｉｓｈ.ｃ」には、開発者が関数を記載する際のアルゴリズムとして、関数定義４２６が記載されている。関数定義４２６には、関数４２７「ｅｎｇｌｉｓｈ」が関数４２８「ａｄｄ」を呼び出すための命令文が記載されている。
【００３６】
図５は、図２および図３に示した中間ファイル２０４〜２０６，２０８，３０４の記述例を示す説明図である。中間ファイル２０４「ｍａｉｎ１.ｏｂｊ」には、開発者が関数を記載する際のアルゴリズムとして、関数５０２、関数５０４、関数５０７、および関数５１０が記載されている。関数５０２は、ラベル５０３「ａｄｄ」の命令文が記載されている。関数５０４には、ラベル５０５「ｍａｔｈ」の副プログラムが関数５０６「ａｄｄ」を呼び出すための命令文が記載されている。関数５０７には、ラベル５０８「ｈｉｓｔｏｒｙ」の副プログラムが関数５０９「ａｄｄ」を呼び出すための命令文が記載されている。関数５１０には、ラベル５１１「ｍａｉｎ」の副プログラムが関数５１２「ｍａｔｈ」、関数５１３「ｈｉｓｔｏｒｙ」、関数５１４「ｓｃｉｅｎｃｅ」、および関数５１５「ｇｅｏｇｒａｐｈｙ」を呼び出すための命令文が記載されている。
【００３７】
また、中間ファイル２０５「ｓｃｉｅｎｃｅ.ｏｂｊ」には、関数５１７が記載されている。関数５１７には、ラベル５１８「ｓｃｉｅｎｃｅ」の副プログラムが関数５１９「ａｄｄ」を呼び出すための命令文が記載されている。また、中間ファイル２０６「ｇｅｏｇｒａｐｈｙ.ｏｂｊ」には、関数５２１が記載されている。関数５２１には、ラベル５２２「ｓｃｉｅｎｃｅ」の副プログラムが関数５２３「ａｄｄ」を呼び出すための命令文が記載されている。
【００３８】
また、ライブラリであるプログラム２０８「ｇｅｏｇｒａｐｈｙ.ｄｌｌ」には、関数５２５が記載されている。関数５２５には、ラベル５２６「ｇｅｏｇｐｒａｈｙ」の副プログラムが関数５２７「ａｄｄ」を呼び出すための命令文が記載されている。
【００３９】
また、プログラム３０４「ｅｎｇｌｉｓｈ．ｄｌｌ」には、関数５２９が記載されている。関数５２９には、ラベル５３０「ｅｎｇｌｉｓｈ」の副プログラムが関数５３１「ａｄｄ」を呼び出すための命令文が記載されている。
【００４０】
なお、図５では本実施例を説明する際に不要なアルゴリズム、例えば関数間の引数を受け渡すために行うスタックへの格納処理等の処理については説明の記載は省略している。また、図５の例では中間ファイルとプログラムを区別しているが、中間ファイルとプログラムには同じ機械語が記載されることもある。り、中間ファイルとプログラムを逆アセンブル処理した場合、同じ命令文の情報を得ることができる場合もあり、その場合には両者を区別しなくともよい。
【００４１】
＜解析結果例および警告例＞
図６は、解析結果例および警告例（その１）を示す説明図である。解析結果画面６０１は、プログラムリスト２０１〜２０３の解析結果例である。解析結果画面６０１は、プログラムリスト２０１〜２０３の解析結果６０３〜６０５を有する。解析結果６０３〜６０５は、コールグラフ６０６〜６０９により表現される。
【００４２】
解析箇所６１１は、図４に示した関数定義４０５の解析結果である。関数４０４（ａｄｄ）は、関数４０６（ｍａｔｈ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、呼び出し遵守と判定される。一方、解析箇所６１２は、図４に示した関数定義４０８の解析結果である。関数４０４（ａｄｄ）は、関数４０９（ｈｉｓｔｏｒｙ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、属性違反と判定される。
【００４３】
警告画面６２０は、解析箇所６１１に応じた警告情報を示す出力画面である。解析箇所６１２が属性違反と判定されるため、その旨の内容を示す文字列である警告情報６２１を有する警告画面６２０が出力される。このように、プログラムリスト１０１の作成時にアノテーション１０を挿入しておくことで、属性違反となる箇所を特定することができる。
【００４４】
図７は、解析結果例および警告例（その２）を示す説明図である。解析結果画面７０１は、中間ファイル２０４〜２０６の解析結果例である。解析結果画面７０１は、中間ファイル２０４〜２０６の解析結果７０２を有する。解析結果７０２は、コールグラフ７０３により表現される。
【００４５】
解析箇所７１１は、図５に示した関数５０４の解析結果である。関数５０４内の関数５０６（ａｄｄ）は、ラベル５０５（ｍａｔｈ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、呼び出し遵守と判定される。一方、解析箇所７１２〜７１４は、図５に示した関数５０７，５１４，５１５の解析結果である。解析箇所７１２において、図５に示した関数５０９（ａｄｄ）は、ラベル５０８で特定される関数５０７（ｈｉｓｔｏｒｙ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、属性違反と判定される。
【００４６】
解析箇所７１３において、図５に示した関数５１９（ａｄｄ）は、関数５１７（ｓｃｉｅｎｃｅ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、属性違反と判定される。
【００４７】
解析箇所７１４において、図５に示した関数５２３（ａｄｄ）は、関数５２１（ｇｅｏｇｒａｐｈｙ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、属性違反と判定される。
【００４８】
警告画面７２０は、解析箇所７１２〜７１４に応じた警告情報を示す出力画面である。解析箇所７１２〜７１４が属性違反と判定されるため、その旨の内容を示す文字列である警告情報７２１を有する警告画面７２０が出力される。このように、プログラムリスト１０１の作成時にアノテーション１０を挿入しておくことで、中間ファイルにおいても、属性違反となる箇所を特定することができる。
【００４９】
図８は、解析結果例および警告例（その３）を示す説明図である。解析結果画面８０１は、プログラム３０１の解析結果例である。解析結果画面８０１は、プログラム３０１の解析結果８０２を有する。解析結果８０２は、コールグラフ８０３により表現される。
【００５０】
解析箇所８１１は、図５に示した関数５２９の解析結果である。関数５２９内の関数５３１（ａｄｄ）は、関数５２９（ｅｎｇｌｉｓｈ）から呼び出されている。したがって、図１に示したフィルタルールＡ１（）が適用されると、属性違反と判定される。
【００５１】
警告画面８２０は、解析箇所８１１に応じた警告情報を示す出力画面である。解析箇所８１１が属性違反と判定されるため、その旨の内容を示す文字列である警告情報８２１を有する警告画面８２０が出力される。このように、プログラムリスト１０１の作成時にアノテーション１０を挿入しておくことで、中間ファイルにおいても、属性違反となる箇所を特定することができる。
【００５２】
＜解析装置のハードウェア構成例＞
図９は、解析装置のハードウェア構成例を示すブロック図である。解析装置９００は、プロセッサ９０１と、記憶デバイス９０２と、入力デバイス９０３と、出力デバイス９０４と、通信インターフェース（通信ＩＦ９０５）と、を有する。プロセッサ９０１、記憶デバイス９０２、入力デバイス９０３、出力デバイス９０４、および通信ＩＦ９０５は、バスにより接続される。プロセッサ９０１は、解析装置９００を制御する。記憶デバイス９０２は、プロセッサ９０１の作業エリアとなる。また、記憶デバイス９０２は、各種プログラムやデータを記憶する非一時的なまたは一時的な記録媒体である。記憶デバイス９０２としては、たとえば、ＲＯＭ（Ｒｅａｄ  Ｏｎｌｙ  Ｍｅｍｏｒｙ）、ＲＡＭ（Ｒａｎｄｏｍ  Ａｃｃｅｓｓ  Ｍｅｍｏｒｙ）、ＨＤＤ（Ｈａｒｄ  Ｄｉｓｋ  Ｄｒｉｖｅ）、フラッシュメモリがある。入力デバイス９０３は、データを入力する。入力デバイス９０３としては、たとえば、キーボード、マウス、タッチパネル、テンキー、スキャナがある。出力デバイス９０４は、データを出力する。出力デバイス９０４としては、たとえば、ディスプレイ、プリンタがある。通信ＩＦ９０５は、ネットワークと接続し、データを送受信する。
【００５３】
＜テーブルの記憶内容例＞
つぎに、解析装置９００で用いられるテーブルの記憶内容例について、図１０〜図１３を用いて説明する。以後の説明では「テーブル」形式によって説明するが、これら情報は必ずしもテーブルによるデータ構造で表現されていなくても良く、リスト、ＤＢ、キュー等のデータ構造やそれ以外で表現されていても良い。そのため、データ構造に依存しないことを示すために「テーブル」、「リスト」、「ＤＢ」、「キュー」等について単に「情報」と呼ぶことがある。また、各情報の内容を説明する際に、「識別情報」、「識別子」、「名」、「名前」、「ＩＤ」という表現を用いることが可能であり、これらについてはお互いに置換が可能である。
【００５４】
図１０は、命令文情報格納テーブル１０００の記憶内容例を示す説明図である。命令文情報格納テーブル１０００は、命令文１００１とアノテーション属性１００２の組み合わせである命令文情報がエントリとして生成されるテーブルである。命令文情報は、どの命令文１００１にどのアノテーション属性１００２が付与されているかを示す情報である。
【００５５】
命令文１００１は、値として、「ａｄｄ」などの関数を格納するフィールドである。アノテーション属性１００２は、値として、アノテーションとして規定された属性を格納するフィールドである。図１に示したアノテーション１０を例に挙げると、命令文１００１の値「ａｄｄ」に対して、アノテーション属性１００２の値「［ｍａｔｈ」が対応付けられる。
【００５６】
図１１は、インターフェース情報格納テーブル１１００の記憶内容例を示す説明図である。インターフェース情報格納テーブル１１００は、インターフェース１１０１と属性１１０２の組み合わせであるインターフェース情報をエントリとしてあらかじめ用意されるテーブルである。インターフェース情報は、どのインターフェース１１０１にどの属性１１０２が付与されているかを示す情報である。
【００５７】
インターフェース１１０１は、値として、命令文またモジュールを格納するフィールドである。具体的には、たとえば、変数、マクロ、テンプレート、関数、クラス、構造体、インライン展開、プロトタイプ宣言、仮想関数等の高級言語の命令文が格納される。また、ニーモニック等の高級言語以外の命令文が格納される。また、アプリケーションやライブラリのファイル名といった、任意の解析対象の実行に必要な命令文やモジュールが格納される。
【００５８】
たとえば、エントリ１１１１のインターフェース１１０１の値は「ａｄｄ」であり、属性１１０２の値は「ＧＰＬｖ３」である。このエントリ１１１１は、関数「ａｄｄ」は、「ＧＰＬｖ３」に適用可能であることを示す。また、エントリ１１１２のインターフェース１１０１の値は「ｅｎｇｌｉｓｈ」であり、属性１１０２の値は「Ｖｕｌｎｅｒａｂｌｅ」（脆弱性）である。このエントリ１１１２は、関数「ｅｎｇｌｉｓｈ」は、「Ｖｕｌｎｅｒａｂｌｅ」（脆弱性）であることを示す。
【００５９】
図１２は、プログラム情報格納テーブル１２００の記憶内容例を示す説明図である。プログラム情報格納テーブル１２００は、呼び出し元１２０１と参照物１２０２と呼び出し形態１２０３の組み合わせがエントリとして生成されるテーブルである。プログラム情報は、どの呼び出し元１２０１がどのような呼び出し形態１２０３でどの参照物１２０２を参照するかを示す情報である。
【００６０】
呼び出し元１２０１は、値として、参照物１２０２を呼び出すファイル（たとえば、プログラムや中間ファイル）の位置を示す情報を格納するフィールドである。たとえば、エントリ１２１１の呼び出し元１２０１の値は、プログラムである「ｍａｉｎ１．ｅｘｅ」の位置を示す情報「／ｈｏｍｅ／ｍａｉｎ１.ｅｘｅ」である。
【００６１】
参照物１２０２は、値として、呼び出し元１２０１から呼び出されるファイル（たとえば、プログラムリストや中間ファイル）の位置情報を格納するフィールドである。たとえば、エントリ１２１１の参照物１２０２の値は、中間ファイルである「ｇｅｏｇｒａｐｈｙ.ｄｌｌ」の位置を示す情報「／ｈｏｍｅ／ｇｅｏｇｒａｐｈｙ.ｄｌｌ」である。
【００６２】
呼び出し形態１２０３は、値として、呼び出し元１２０１が参照物１２０２を呼び出す場合のタイミングを格納するフィールドである。たとえば、エントリ１２１１の呼び出し形態１２０３の値は、「実行時の構成要素」である。
【００６３】
ここで、エントリ１２１１〜１２１４について具体的に説明する。エントリ１２１１は、呼び出し元１２０１の値「／ｈｏｍｅ／ｍａｉｎ１.ｅｘｅ」で特定される呼び出し元「ｍａｉｎ１.ｅｘｅ」が、呼び出し形態１２０３の値「実行時の構成要素」として参照物１２０２の値「／ｈｏｍｅ／ｇｅｏｇｒａｐｈｙ.ｄｌｌ」で特定される参照物「ｇｅｏｇｒａｐｈｙ.ｄｌｌ」を呼び出すプログラム情報である。「実行時の構成要素」とは、例えば、参照物が呼び出し元の起動時に参照されるファイルであることを示す呼び出し形態である。
【００６４】
エントリ１２１２は、呼び出し元１２０１の値「／ｈｏｍｅ／ｍａｉｎ２.ｅｘｅ」で特定される呼び出し元「ｍａｉｎ２.ｅｘｅ」が、呼び出し形態１２０３の値「実行時の読み込み要素」として参照物１２０２の値「／ｄｏｗｎｌｏａｄ／Ｅｎｇｌｉｓｈ.ｄｌｌ」で特定される参照物「Ｅｎｇｌｉｓｈ.ｄｌｌ」を呼び出すプログラム情報である。「実行時の読み込み要素」とは、例えば、参照物が呼び出し元の実行中に参照されるファイルであることを示す呼び出し形態である。
【００６５】
エントリ１２１３は、呼び出し元１２０１の値「／ｈｏｍｅ／ｍａｉｎ１.ｅｘｅ」で特定される呼び出し元「ｍａｉｎ１.ｅｘｅ」が、呼び出し形態１２０３の値「コード生成時の構成要素」として参照物１２０２の値「／ｈｏｍｅ／ｍａｉｎ１.ｏｂｊ」で特定される参照物「ｍａｉｎ１.ｏｂｊ」を呼び出すプログラム情報である。「コード生成時の構成要素」とは、例えば、参照物がコード生成時に参照されるファイルであることを示す呼び出し形態である。
【００６６】
エントリ１２１４は、呼び出し元１５０７の値「／ｈｏｍｅ／ｍａｉｎ１.ｅｘｅ」で特定される呼び出し元「ｍａｉｎ１.ｅｘｅ」が、呼び出し形態１２０３の値「構文解析時の構成要素」として参照物１２０２の値「／ｈｏｍｅ／ｍａｉｎ１.ｃ」で特定される参照物「ｍａｉｎ１.ｃ」を呼び出すプログラム情報である。「構文解析時の構成要素」とは、例えば、参照物が構文解析時に参照されるファイルであることを示す呼び出し形態である。
【００６７】
図１３は、フィルタルール情報格納テーブル１３００の記憶内容例を示す説明図である。フィルタルール情報格納テーブル１３００は、属性１３０１とフィルタルール１３０２の組み合わせであるフィルタルール情報をエントリとしてあらかじめ用意されるテーブルである。フィルタルール情報は、どのフィルタルール１３０２がどの属性１３０１に適用されるかを示す情報である。
【００６８】
属性１３０１は、値として、フィルタルール１３０２を特定する文字列を格納するフィールドである。属性１３０１の値は、解析対象から検出される。フィルタルール１３０２は、値として、属性１３０１の値が解析対象から検出された場合に呼び出される関数を格納するフィールドである。フィルタルール１３０２の値である関数は、あらかじめ定義される。具体的には、たとえば、フィルタルール１３０２は、属性１３０１の値が付与されている命令文情報格納テーブル１０００の命令文情報やインターフェース情報格納テーブル１６００のインターフェース情報の検査を行う関数である。フィルタルール１３０２の値としては、例えば、関数ポインタのアドレス、関数名、またはシンボル情報が格納される。
【００６９】
フィルタルール１３０２による処理では、例えば、命令文１００１やインターフェース１１０１に付与された属性１００２，１１０２に対する呼び出し違反の検出や、命令文１００１やインターフェース１１０１に付与された属性１００２，１１０２の波及の検出が実行される。
【００７０】
呼び出し違反の検出とは、例えば、命令文Ｂ（たとえば、「ａｄｄ」）の呼び出しだけを許可するアノテーション属性ａ（たとえば、「［ｍａｔｈ」）が命令文Ａ（たとえば、「ｍａｔｈ」）に付与されている場合、命令文Ａが命令文Ｃ（たとえば、「ｈｉｓｔｏｒｙ」）を呼び出している場合に属性違反として検出する処理である。例えば、開発者が意図しない命令文の呼び出しが行われるのを禁止するために利用される。
【００７１】
属性の波及の検出とは、例えば、命令文Ａ（たとえば、「ｍａｔｈ」）が命令文Ｂ（たとえば、「ａｄｄ」）を呼び出していた場合、命令文Ｂに付与されている属性ｂ（たとえば、アノテーションの属性「ＧＰＬｖ３」）が命令文Ａにも付与されると推定する処理である。例えば、ライセンス伝播や脆弱性の影響範囲の検出を行うために利用される。
【００７２】
なお、フィルタルール１３０２の値である関数は、同一関数であってアルゴリズムが異なるため、後述するディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）と、構文解析木による依存関係抽出処理（ステップＳ１８００）とで、別々に用意される。
【００７３】
＜解析装置９００の機能的構成例＞
図１４は、解析装置９００の機能的構成例を示すブロック図である。解析装置９００は、構文解析部１４０１と、生成部と、実行部１４０３と、を含む構成である。構文解析部１４０１、生成部、および実行部１４０３は、具体的には、たとえば、図９に示したプロセッサに、記憶デバイスに記憶された解析プログラムを実行させることによりその機能を実現する。構文解析部１４０１は、プログラムリストについて後述する図１６〜図１９に示す処理を実行して、プログラムリストから中間ファイルを生成する。また、構文解析部１４０１は、解析結果として図６に示した情報を生成して出力する。生成部は、中間ファイルについて後述する図２０〜図２３に示す処理を実行して、プログラム（実行ファイル）を生成する。また、生成部は、解析結果として図７に示した情報を生成して出力する。実行部１４０３は、プログラム（実行ファイル）について後述する図２４〜図２７に示す処理を実行する。また、実行部１４０３は、解析結果として図８に示した情報を生成して出力する。実行部１４０３は、たとえば、プロセッサ９０１がプログラム（実行ファイル）を実行するプロセスに相当する。
【００７４】
＜構文解析木＞
図１５は、解析装置９００の構文解析で取得される構文解析木の例を示す説明図である。図１５では、例として３個の構文解析木１５０１〜１５０３について説明する。構文解析木１５０１は、図４に示したプログラムリスト２０１の関数定義４１１に対応する構文解析木である。構文解析木１５０２は、図４に示したプログラムリスト２０１の関数定義４０２に対応する構文解析木である。構文解析木１５０３は、図４に示したプログラムリスト２０１の関数定義４０５に対応する構文解析木である。
【００７５】
構文解析木１５０１は、根ノード１５１０からの枝となるノード１５１１〜１５１３を有する。ノード１５１１〜１５１３は、「ｉｎｔ」型（ノード１５１１）の関数「ｍａｉｎ」（ノード１５１２）のアルゴリズムをノード１５１３から伸びる枝で定義する。すなわち、ノード１５１３は、関数４１２「ｍａｉｎ」のブロックである関数定義４１１の「｛｝」の中身を指している。
【００７６】
ノード１５１３からの枝のうち、例えば、ノード１５１４は、関数４１３「ｍａｔｈ」、ノード１５１５は実引数「１」、およびノード１５１６は実引数「２」を指している。ノード１５１４〜１５１６は、関数４１３「ｍａｔｈ」が「１」、「２」を引数として受け取り呼び出されるということを意味している。このような構文解析木１５０１を探索すると、関数４１２「ｍａｉｎ」が呼び出す関数は、関数４１３「ｍａｔｈ」、関数４１４「ｈｉｓｔｏｒｙ」、関数４１５「ｓｃｉｅｎｃｅ」、および関数４１６「ｇｅｏｇｒａｐｈｙ」であることがわかる。
【００７７】
同様にして、構文解析木１５０２は、根ノード１５２０からの枝であるノード１５２１により、「ｉｎｔ」型の関数４０４「ａｄｄ」が定義されていることを意味する。また、ノード１５２２「＊ｖａｒ＊」は変数定義を意味しており、ノード１５２３およびノード１５２４の並びにより、「ｉｎｔ」型（ノード１５２４）の変数「ａ」（ノード１５２３）を仮引数（ノード１５２２）が定義されていることを表す。また同様にして、構文解析木１５０２には、「ｉｎｔ」型の変数「ｂ」が仮引数として定義されている。
【００７８】
また、ノード１５２６から伸びた枝であるノード１５２５の「ｒｅｔｕｒｎ」と、ノード１５２６から伸びた枝であるノード１５２７の「＋」演算子、ノード１５２８の変数「ａ」、およびノード１５２９の変数「ｂ」により、関数４０４「ａｄｄ」（ノード１５２１）は、変数「ａ」（ノード１５２８）と変数「ｂ」（ノード１５２９）を「＋」演算（ノード１５２７）した値を「ｒｅｔｕｒｎ」（ノード１５２５）していることを意味する。
【００７９】
構文解析木１５０２の探索により、関数定義４０２で規定される「ｉｎｔ」型の関数４０４「ａｄｄ」（ノード１５２１）は、別の関数の呼び出しを行っていないことがわかる。
【００８０】
同様にして、構文解析木１５０３は、根ノード１５３０からの枝であるノード１５３１で「ｉｎｔ」型の関数４０６「ｍａｔｈ」を定義している。また、ノード１５３２の関数４０４「ａｄｄ」、ノード１５３３の変数「ｃ」、およびノード１５３４の変数「ｄ」の並びは、関数４０４「ａｄｄ」の実引数に変数「ｃ」および変数「ｄ」を渡し、関数４０４「ａｄｄ」を呼び出すということを意味する。構文解析木１５０３の探索により、関数定義４０５で規定される関数４０６「ｍａｔｈ」（ノード１５３１）は、関数４０７「ａｄｄ」（ノード１５３２）を呼び出していることがわかる。
【００８１】
なお、構文解析木１５０１〜１５０３をどのように探索かはコンパイラの実装によるため、コンパイラに都合のよい構文解析木を取得することにより、構文解析木１５０１〜１５０３の探索が実行される。
【００８２】
＜構文解析部１４０１による構文解析処理例＞
つぎに、構文解析部１４０１による構文解析処理例について説明する。構文解析部１４０１による構文解析処理では、解析対象としてプログラムリストを解析することにより、プログラムリストを構文解析する処理である。
【００８３】
図１６は、構文解析部１４０１による構文解析処理例を示すフローチャートである。構文解析部１４０１は、ユーザ操作によるプログラムリストのファイルをオープンする（ステップＳ１６０１）。つぎに、構文解析部１４０１は、オープンしたファイルの情報をメモリに記憶する（ステップＳ１６０２）。そして、構文解析部１４０１は、インターフェース情報格納テーブル１１００を用いてプログラムリストから属性１１０２を検索する（ステップＳ１６０３）。
【００８４】
つぎに、構文解析部１４０１は、フィルタルール情報格納テーブル１３００から、検索した属性１１０２に一致する属性１３０１と、当該属性１３０１に対応するフィルタルール１３０２との組み合わせであるエントリ（フィルタルール情報）を取得する（ステップＳ１６０４）。
【００８５】
つぎに、構文解析部１４０１は、プログラムリストに記載された命令文を命令文情報格納テーブル１０００の命令文１００１に、プログラムリストに記載された命令文に対応するアノテーション属性を命令文情報格納テーブル１０００のアノテーション属性１００２に格納する（ステップＳ１６０５）。なお、ステップＳ１６０５の処理では、プログラムリストに記載された命令文と当該命令文に対応するアノテーション属性を検索するために、例えば、構文解析部１４０１は、プログラムリストを変換する前準備として行うプリプロセス処理における情報を監視してもよい。例えば、構文解析部１４０１は、では、プログラムリストに記載された命令文の変換処理を行う前に、命令文の展開を行う等のプリプロセス処理を動作させることがある。
【００８６】
このプリプロセス処理を監視することで、プログラムリストに記載された命令文と命令文に対応するアノテーション属性の組み合わせである命令文情報を取得することができる。なお、必ずしもステップＳ１００５において命令文情報格納テーブル１０００に対して格納処理を行う必要はなく、例えば、コンパイル処理等が該当する構文解析処理を監視することで、構文解析部１４０１は、同様の情報を取得して命令文情報格納テーブル１０００に格納してもよい。なお、プリプロセス処理やコンパイル処理といった具体的な処理は構文解析部１４０１の実装に依存する。したがって、プログラムリストに記載された命令文と当該命令文に対応するアノテーション属性を検索する処理は、構文解析部１４０１の実装に合わせて適用される。
【００８７】
このあと、構文解析部１４０１は、プログラムリストの探索開始位置を探索して（ステップＳ１６０６）、依存関係抽出処理を実行する（ステップＳ１６０７）。依存関係抽出処理（ステップＳ１６０７）は２種類ある。１つは、ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）であり、もう１つは、構文解析木による依存関係抽出処理（ステップＳ１８００）である。いずれかの一方の抽出処理があらかじめ設定される。
【００８８】
ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）では、構文解析部１４０１がプログラムリストを構文解析しつつ依存関係の抽出を実行するため、構文解析木を生成する必要がない。したがって、依存関係抽出処理（ステップＳ１６０７）の処理速度の向上を図ることができる。
【００８９】
また、構文解析木による依存関係抽出処理（ステップＳ１８００）では、構文解析部１４０１が、依存関係抽出に先立って構文解析木を生成し、依存関係の抽出に構文解析木を用いる。構文解析木を用いることにより、プログラムリストに記載される命令文の記述の違いを吸収することができる。なお、記述の違いとは、例えば、関数定義４０２において属性４０３と関数４０４の間にスペースや改行コードが任意の数だけ挿入されている等、命令文のアルゴリズムに影響を与えない文字列の違いをいう。
【００９０】
ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）については図１７で説明する。構文解析木による依存関係抽出処理（ステップＳ１８００）については、図１８および図１９で説明する。
【００９１】
依存関係抽出処理（ステップＳ１６０７）のあと、構文解析部１４０１は、依存関係抽出処理（ステップＳ１６０７）でのコンパイル（ステップＳ１９０８）で得られる中間ファイルを保存する（ステップＳ１６０８）。そして、構文解析部１４０１は、プログラム情報格納テーブル１２００に、ステップＳ１６０８で保存された中間ファイルのプログラム情報を格納する（ステップＳ１６０９）。ステップＳ１６０９では、例えば、構文解析部１４０１は、ステップＳ１６０８で保存された中間ファイルへのファイルパスをプログラム情報格納テーブル１２００の呼び出し元１２０１に格納し、ステップＳ１６０２で記憶したファイルのファイルパスを参照物１２０２に格納する。これにより変換前後のプログラムリストと中間ファイルの格納場所を対応付けることができる。
【００９２】
そして、ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）の場合は、構文解析部１４０１は、「ディスパッチテーブル登録による構文解析時の構成要素」という文字列を呼び出し形態１２０３に格納する。構文解析木による依存関係抽出処理の場合は、構文解析部１４０１は、「構文解析木による構文解析時の構成要素」という文字列を呼び出し形態１２０３に格納する。これにより、プログラム情報がプログラム情報格納テーブル１２００に格納される。
【００９３】
そして、構文解析部１４０１は、構文解析結果を生成して出力する（ステップＳ１６１０）。構文解析結果とは、たとえば、図６に示した解析結果画面６０１である。また、属性違反がある場合には警告画面６２０を出力してもよい。
【００９４】
＜ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）＞
図１７は、ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）の詳細な処理手順例を示すフローチャートである。ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）は、図１６に示した依存関係抽出処理（ステップＳ１６０７）で実行される処理である。
【００９５】
まず、構文解析部１４０１は、Ｓ１６０４で取得したフィルタルール情報をディスパッチテーブルに登録する（ステップＳ１７０１）。Ｓ１６０４で取得したフィルタルール情報は、特定の属性を検出した際に呼び出すフィルタルールを含む。次に、構文解析部１４０１は、プログラムリストの先頭行を取得し（ステップＳ１７０２）、プログラムリストの終端であるかを判定する（ステップＳ１７０３）。プログラムリストの終端でない場合（ステップＳ１７０３：Ｎｏ）、構文解析部１４０１は、取得した行が命令文の呼び出しをする関数を含むか否かを判定する（ステップＳ１７０４）。命令文の呼び出しをする関数を含まない場合（ステップＳ１７０４：Ｎｏ）、構文解析部１４０１は、次の行を取得し（ステップＳ１７０５）、ステップＳ１７０３に戻る。
【００９６】
命令文の呼び出しである場合（ステップＳ１７０４：Ｙｅｓ）、構文解析部１４０１は、命令文に未だ取得していないアノテーションが付与されているかを判定する（ステップＳ１７０６）。具体的には、たとえば、構文解析部１４０１は、当該命令文がアノテーション属性１００２に含まれる関数（たとえば、図１の関数１３）に該当するか否かを判定する。命令文に未だ取得していないアノテーションが付与されていない場合（ステップＳ１７０６：Ｎｏ）、構文解析部１４０１は、次の行を取得し（ステップＳ１７０５）、ステップＳ１７０３に戻る。
【００９７】
命令文に未だ取得していないアノテーションが付与されている場合（ステップＳ１７０６：Ｙｅｓ）、構文解析部１４０１は、当該アノテーションを取得する（ステップＳ１７０７）。つぎに、構文解析部１４０１は、取得したアノテーションに対応するフィルタルールがディスパッチテーブルに登録されているかを判定する（ステップＳ１７０８）。登録されていない場合（ステップＳ１７０８：Ｎｏ）、ステップＳ１７０６に戻る。
【００９８】
一方、登録されている場合（ステップＳ１７０８：Ｙｅｓ）、構文解析部１４０１は、取得したアノテーションに対応するフィルタルールによる処理を実行する（ステップＳ１７０９）。フィルタルールによる処理を実行した結果、構文解析部１４０１は、取得した命令文がフィルタルールに適合するか否かを判定する（ステップＳ１７１０）。具体的には、構文解析部１４０１は、フィルタルールが属性違反を検出する関数であれば、属性違反であるか否かを判定し、フィルタルールが属性波及を検出する関数であれば、属性波及であるか否かを判定する。属性違反であったり属性波及である場合は、フィルタルールに適合することになる。
【００９９】
フィルタルールに適合する場合（ステップＳ１７１０：Ｙｅｓ）、構文解析部１４０１は、フィルタルールに応じた制御処理を実行して（ステップＳ１７１１）、ステップＳ１７０６に戻る。ここで、フィルタルールに応じた制御処理とは、たとえば、フィルタルールが属性違反を検出する関数である場合、取得した命令文を、属性を遵守する命令文に置き換える処理となる。
【０１００】
たとえば、図１の記述箇所１１２における「ｉｎｔ  ｈｉｓｔｏｒｙ  （ｉｎｔ  ｅ，ｉｎｔ  ｆ）」は、フィルタルールＡ（）の実行により、属性違反と判定される。したがって、構文解析部１４０１は、「ｉｎｔ  ｈｉｓｔｏｒｙ  （ｉｎｔ  ｅ，ｉｎｔ  ｆ）」の命令文「ｈｉｓｔｏｒｙ」を、属性を遵守する命令文「ｍａｔｈ」に置き換える。
【０１０１】
また、必ずしも命令文の置き換えを実行する必要はなく、構文解析部１４０１は、警告画面１０３を生成して、ステップＳ１６０９で警告画面１０３を出力することとしてもよい。また、図示はしないが、構文解析部１４０１は、ステップＳ１７１１において、上記置き換えを実行し、さらに、命令文「ｈｉｓｔｏｒｙ」から属性を遵守する命令文「ｍａｔｈ」に置き換えた旨を示す確認画面を生成して、ステップＳ１６０９で確認画面を出力することとしてもよい。
【０１０２】
また、フィルタルールが属性波及を検出する関数である場合、フィルタルールに応じた制御処理は、取得した命令文の属性が他の命令文に波及していることを示す警告画面を生成する処理となる。警告画面は、ステップＳ１６０９で出力される。
【０１０３】
このあと、構文解析部１４０１は、命令文をコンパイルして（ステップＳ１７１２）、ステップＳ１７０６に戻る。また、ステップＳ１７０３において、プログラムリストの終端である場合（ステップＳ１７０３：Ｙｅｓ）、構文解析部１４０１は、ディスパッチテーブル登録による依存関係抽出処理（ステップＳ１７００）を終了し、プログラムリストを保存する（ステップＳ１６０７）。
【０１０４】
＜構文解析木による依存関係抽出処理（ステップＳ１８００）＞
図１８は、構文解析木による依存関係抽出処理（ステップＳ１８００）の詳細な処理手順例（前半）を示すフローチャートである。構文解析木による依存関係抽出処理（ステップＳ１８００）は、図１６に示した依存関係抽出処理（ステップＳ１６０７）で実行される処理である。なお、構文解析木による依存関係抽出処理（ステップＳ１８００）では、スタックＡとカウンタＢを用いる。スタックＡには、命令文がプッシュされる。カウンタＢは、スタックＡに命令文がプッシュされた回数を計数する。スタックＡの初期状態は空であり、カウンタＢの初期値は０である。尚、データを保存するのに、必ずしもスタックである必要はなく、ヒープまたは静的なメモリ確保によるオンメモリでの処理を行う方法や、ファイルとして出力して保持して処理を行う方法を用いてもよい。
【０１０５】
まず、構文解析部１４０１は、構文解析を実行する（ステップＳ１８０１）。つぎに、構文解析部１４０１は、構文解析結果として構文解析木が取得できるか否かを判定する（ステップＳ１８０２）。取得できない場合（ステップＳ１８０２：Ｎｏ）、構文解析木がないため、構文解析部１４０１は、構文解析木による依存関係抽出処理（ステップＳ１８００）を終了し、プログラムリストを保存する（ステップＳ１６０７）。
【０１０６】
一方、取得できる場合（ステップＳ１８０２：Ｙｅｓ）、構文解析木を取得する（ステップＳ１８０３）。つぎに、構文解析部１４０１は、内部カウンタＢの値を０にセットし（ステップＳ１８０４）、構文解析木に未訪問ノードが存在するか否かを判定する（ステップＳ１８０５）。未訪問ノードとは、構文解析木の探索において、未探索のノードをいう。未訪問ノードが存在しない場合（ステップＳ１８０５：Ｎｏ）、構文解析部１４０１は、カウンタＢの値の回数分、スタックＡをポップすることにより廃棄する（ステップＳ１８０５）。そして、ステップＳ１８０２に戻り、構文解析部１４０１は、次の構文解析木の取得を試行する（ステップＳ１８０２）。
【０１０７】
未訪問ノードが存在する場合（ステップＳ１８０５：Ｙｅｓ）、構文解析部１４０１は、未訪問ノードを探索する（ステップＳ１８０６）。つぎに、構文解析部１４０１は、未訪問ノードに隣接ノードが存在するか否かを判定する（ステップＳ１８０７）。隣接ノードとは、未訪問ノードと同一階層の未訪問ノードである。たとえば、図１５の構造解析木１５０１において、ノード１５１１〜１５１３が未訪問ノードである場合、ノード１５１１，１５１２，１５１３の順に探索される。未訪問ノードが探索された場合、訪問済みとなるため、隣接ノードに該当しない。
【０１０８】
たとえば、未訪問ノードがノード１５１１である場合、ノード１５１２，１５１３は未訪問ノードであるため、隣接ノードとなる。ノード１５１２，１５１３が探索された場合、すでに訪問済みであるため、未訪問ノードとして探索されない。
【０１０９】
隣接ノードが存在しない場合（ステップＳ１８０８：Ｎｏ）、ステップＳ１８１０に移行する。一方、隣接ノードが存在する場合（ステップＳ１８０８：Ｙｅｓ）、構文解析部１４０１は、隣接ノードを取得する（ステップＳ１８０８）。つぎに、構文解析部１４０１は、ノードの並びが命令文の定義を示す並びであるか否かを判定する（ステップＳ１８０９）。たとえば、ノードの並びが、型、命令文の順である場合は、命令文の定義に該当する。たとえば、ノード１５１１〜１５１３の並びは、命令文の定義に該当する。また、ノードの並びが命令文、引数の順である場合も、命令文の定義に該当する。たとえば、ノード１５１４〜１５１６の並びは、命令文の定義に該当する。一方、先頭に変数定義「＊ｖａｒ＊」がある場合は、命令文の定義に該当しない。たとえば、ノード１５２２〜１５２４の並びは、命令文の定義に該当しない。
【０１１０】
命令文の定義を示すノードの並びでない場合（ステップＳ１８１０：Ｎｏ）、ステップＳ１８０５に戻る。一方、命令文の定義を示すノードの並びである場合（ステップＳ１８１０：Ｙｅｓ）、構文解析部１４０１は、命令文の定義に該当した命令文をスタックＡにプッシュして（ステップＳ１８１１）。カウンタＢをインクリメントする（ステップＳ１８１２）。そして、図１９のステップＳ１９０１に移行する。
【０１１１】
図１９は、構文解析木による依存関係抽出処理（ステップＳ１８００）の詳細な処理手順例（後半）を示すフローチャートである。構文解析部１４０１は、カウンタＢのインクリメント（ステップＳ１８１２）のあと、スタックＡにプッシュした命令文をキーとして、命令文情報格納テーブル１０００からアノテーション属性１００２を検索するとともに、インターフェース情報格納テーブル１１００から属性１１０２を検索する（ステップＳ１９０１）。
【０１１２】
そして、構文解析部１４０１は、検索したアノテーション属性１００２に含まれる属性と検索した属性１１０２とが一致するか否かを判断する（ステップＳ１９０２）。不一致である場合（ステップＳ１９０２：Ｎｏ）、ステップＳ１９０８に移行する。一方、一致する場合（ステップＳ１９０２：Ｙｅｓ）、構文解析部１４０１は、一致した属性１１０２をキーとして、フィルタルール情報格納テーブル１３００から対応するフィルタルール１３０２を検索する（ステップＳ１９０３）。
【０１１３】
フィルタルールが検索できなかった場合（ステップＳ１９０４：Ｎｏ）、ステップＳ１９０８に移行する。一方、フィルタルールが検索できた場合（ステップＳ１９０４：Ｙｅｓ）、構文解析部１４０１は、検索されたフィルタルールによる処理を実行する（ステップＳ１９０５）。ステップＳ１９０５では、構文解析部１４０１は、スタックＡに格納された全命令文の呼び出し関係を判定する。フィルタルールによる処理を実行した結果、構文解析部１４０１は、取得した命令文がフィルタルールに適合するか否かを判定する（ステップＳ１９０６）。
【０１１４】
具体的には、構文解析部１４０１は、フィルタルールが属性違反を検出する関数であれば、属性違反であるか否かを判定し、フィルタルールが属性波及を検出する関数であれば、属性波及であるか否かを判定する。属性違反であったり属性波及である場合は、フィルタルールに適合することになる。
【０１１５】
フィルタルールに適合しない場合（ステップＳ１９０６：Ｎｏ）、ステップＳ１９０８に移行する。一方、フィルタルールに適合する場合（ステップＳ１９０６：Ｙｅｓ）、構文解析部１４０１は、フィルタルールに応じた制御処理を実行する（ステップＳ１９０７）。ここで、フィルタルールに応じた制御処理については、図１７のＳ１７１１で説明した内容と同一であるため、説明を省略する。そして、ステップＳ１９０８に移行する。ステップＳ１９０８では、構文解析部１４０１は、キーにした命令文をコンパイルして（ステップＳ１９０８）、図１８のＳ１８０５に戻る。
【０１１６】
なお、本例では、構文解析木に深さ優先探索アルゴリズムを用いたり隣接ノードの並びの解釈が図１５のような構文解析木となることを前提で説明しているが、構文解析や構文解析木の探索アルゴリズムは、コンパイルに合わせて実装される。なお、字句解析、構文解析、および意味解析は、１つの処理として実装してもよいし、各々の解析は実装によって省略することも可能である。また、各々の解析の間にコンパイルによる独自の処理が付加されてもよく、また、各々の処理を分離したプログラムとしてもよい。
【０１１７】
また、本例では構文解析は上昇型や下降型等、どのような方式による構文解析でもよい。構文解析の結果として得られる構文解析木は、解析木、構文木、抽象構文等、どのような構造でもよい。また、データ構造として保持する場合も、例えば、リスト構造等が考えられるが、どのようなデータ構造でもよいし、データ構造として保持せず構文解析の結果を構文解析中にパイプ処理等を用いて受け渡してもよい。すなわち、コンパイルに都合のよいデータとして保持すればよい。
【０１１８】
また、構文解析のノード探索方法は、幅優先探索で説明したが、構文解析木を探索できる方法で例えば、深さ優先探索等、どのような方式で実装してもよい。また、構文解析木は、本フローチャートの例では、関数定義ごとに取得していたが、プログラム構造全てを一つの構文木として纏めてもよく、コンパイルに都合のよい構文木を用いればよい。構文解析、および構文解析木の探索が無限ループに陥らないよう、実装には無限ループを取り除く処理をいれてもよい。
【０１１９】
＜生成部１４０２による解析処理例＞
つぎに、生成部１４０２による解析処理例について説明する。生成部１４０２による解析処理では、解析対象として、プログラムリスト２０１〜２０３をコンパイルしたオブジェクトコードなどの中間ファイル２０４〜２０６やＤＬＬなどリンク相手となるプログラム２０８，３０４を解析する処理である。生成部１４０２による解析処理例において、特に断りがない限り、「中間ファイル」には、リンク相手のプログラムが含まれる。
【０１２０】
図２０は、生成部１４０２による解析処理例を示すフローチャートである。生成部１４０２は、ユーザ操作により中間ファイルをオープンする（ステップＳ２００１）。つぎに、生成部１４０２は、オープンした中間ファイルの情報をメモリに記憶する（ステップＳ２００２）。そして、生成部１４０２は、インターフェース情報格納テーブル１１００を用いて中間ファイルから属性１１０２を検索する（ステップＳ２００３）。
【０１２１】
つぎに、生成部１４０２は、フィルタルール情報格納テーブル１３００から、検索した属性１１０２に一致する属性１３０１と、当該属性１３０１に対応するフィルタルール１３０２との組み合わせであるエントリ（フィルタルール情報）を取得する（ステップＳ２００４）。そして、生成部１４０２は、中間ファイルの探索開始位置を探索して（ステップＳ２００５）、依存関係抽出処理を実行する（ステップＳ２００６）。依存関係抽出処理（ステップＳ２００６）については図２１〜図２３で説明する。
【０１２２】
依存関係抽出処理（ステップＳ２００６）のあと、生成部１４０２は、依存関係抽出処理（ステップＳ２００６）のリンク処理（ステップＳ２３０５）で得られるプログラム（実行ファイル）を保存する（ステップＳ２００７）。そして、生成部１４０２は、プログラム情報格納テーブル１２００に、ステップＳ２００７で保存された中間ファイルのプログラム情報を格納する（ステップＳ２００８）。ステップＳ２００８では、例えば、生成部１４０２は、ステップＳ２００７で保存された中間ファイルのファイルパスをプログラム情報格納テーブル１２００の呼び出し元１２０１に格納し、ステップＳ２００２で記憶したファイルのファイルパスを参照物１２０２に格納する。これにより変換前後の中間ファイルとプログラム（実行ファイル）の格納場所を対応付けることができる。
【０１２３】
そして、生成部１４０２は、「コード生成時の構成要素」という文字列を呼び出し形態１２０３に格納する（ステップＳ２００９）。これにより、プログラム情報がプログラム情報格納テーブル１２００に格納される。そして、生成部１４０２は、構文解析結果を生成して出力する（ステップＳ２０１０）。構文解析結果とは、たとえば、図７に示した解析結果画面７０１である。また、属性違反がある場合には警告画面７２０を出力してもよい。
【０１２４】
＜依存関係抽出処理（ステップＳ２００６）＞
図２１〜図２３は、図２０に示した依存関係抽出処理（ステップＳ２００６）の詳細な処理手順例を示すフローチャート１〜３である。依存関係抽出処理（ステップＳ２００６）では、生成部１４０２は、中間ファイル２０４〜２０６からリンク処理などによってプログラム２０７，２０８を生成する際に、中間ファイル２０４〜２０６における依存関係を抽出する。なお、プログラム２０７，２０８の生成後に解析する場合、本実施例においては説明の行いやすさからプログラム２０７，２０８に対して逆アセンブルを行い、人間に可読なニーモニックに変換してから構文解析を行ってもよい。しかし、実際には必ずしも逆アセンブルの処理は必要なく、アセンブル言語は機械語と一対一対応であるから、本質的には機械語に対してそのまま適用してもよい。生成部１４０２の仕様に合わせてコード生成処理は実装される。
【０１２５】
また、依存関係抽出処理（ステップＳ２００６）において、データを保存する方法としてスタックが用いられるが、必ずしもスタックである必要はなく、ヒープまたは静的なメモリ確保によるオンメモリでの処理を行う方法や、ファイルとして出力して保持して処理を行う方法を用いてもよい。
【０１２６】
まず、図２１において、生成部１４０２は、変数Ｖに文字列「ｍａｉｎ」をセットし（ステップＳ２１０１）、中間ファイルの先頭行を取得する（ステップＳ２１０２）。たとえば、図５に示した中間ファイル２０４の場合、生成部１４０２は、先頭行の関数５０２のラベル５０３（ａｄｄ）を取得する。
【０１２７】
つぎに、生成部１４０２は、取得した行がコードの終端であるかを判定する（ステップＳ２１０３）。取得した行がコードの終端である場合（ステップＳ２１０３：Ｙｅｓ）、生成部１４０２は、依存関係抽出処理を終了する。
【０１２８】
一方、取得した行がコードの終端でない場合（ステップＳ２１０３：Ｎｏ）、生成部１４０２は、取得した行が、変数Ｖが示すラベルの開始アドレスかを判定する（ステップＳ２１０４）。上記の場合、取得した行は、関数５０２の行であるため、ラベル５０３は「ａｄｄ」である。変数Ｖは「ｍａｉｎ」であるため、取得した行が関数５１０の「ｍａｉｎ」が存在する行となるまで（ステップＳ２１０４：Ｎｏ）、生成部１４０２は次の行を取得し（ステップＳ２１０５）、ステップＳ２１０３に戻る。
【０１２９】
一方、取得した行が、変数Ｖの示すラベルの開始アドレスの場合（ステップＳ２１０４：Ｙｅｓ）、生成部１４０２は、変数Ｖに格納された文字列をスタックＳにプッシュし（ステップＳ２１０６）、次の行を取得する（ステップＳ２１０７）。ここまでの処理で、「ｍａｉｎ」の先頭が参照されている状態となる。なお、プログラムの開始地点が見つかればよいので、「ｍａｉｎ」は中間ファイルのスタート地点のラベル名にあわせて変更してもよい。
【０１３０】
つぎに、生成部１４０２は、取得した行がコードの終端であるかを判定し（ステップＳ２１０８）、コードの終端である場合（ステップＳ２１０８：Ｙｅｓ）、生成部１４０２は、依存関係抽出処理を終了する。一方、コードの終端でない場合（ステップＳ２１０８：Ｎｏ）、生成部１４０２は、ラベルの終端であるかを判定する（ステップＳ２１０９）、ラベルの終端である場合（ステップＳ２１０９：Ｙｅｓ）、ステップＳ２１０３に戻る。
【０１３１】
ラベルの終端でない場合（ステップＳ２１０９：Ｎｏ）、生成部１４０２は、ステップＳ２１０７で取得した行がニーモニックであるかを判定する（ステップＳ２１１０）。生成部１４０２は、例えば、取得した行にアドレス番号が存在すれば、ニーモニックであると判定する。
【０１３２】
ニーモニックでない場合（ステップＳ２１１０：Ｎｏ）、生成部１４０２は、次の行を取得する（ステップＳ２１１１）。これにより、例えば、中間ファイル５０１，５１６，５２０や中間ファイルのリンク相手となるプログラム５２４，５２８の中に記載されているコメントアウト等のテキストを読み飛ばすことが可能となる。ニーモニックである場合（ステップＳ２１１０：Ｙｅｓ）、生成部１４０２は、取得した行からオペコードを取得する（ステップＳ２１１２）。このあと、図２２のステップＳ２２０１に移行する。
【０１３３】
図２２において、生成部１４０２は、ステップＳ２１１２で取得したオペコードがリターン命令であるかを判定する（ステップＳ２２０１）。リターン命令でない場合（ステップＳ２２０１：Ｎｏ）、ステップＳ２２０４に移る。リターン命令である場合（ステップＳ２２０１：Ｙｅｓ）、生成部１４０２は、スタックＳから文字列を１つポップし（ステップＳ２２０２）、ポップして取得した文字列を変数Ｖにセットして（ステップＳ２２０３）、ステップＳ２１０２に戻る。
【０１３４】
ステップＳ２１１２で取得したオペコードがリターン命令でない場合（ステップＳ２２０１：Ｎｏ）、生成部１４０２は、取得したオペコードが呼び出し命令であるかを判定する（ステップＳ２２０４）。呼び出し命令でない場合（ステップＳ２２０４：Ｎｏ）、図２１のステップＳ２１０７に戻って、生成部１４０２は、次の行を取得する（ステップＳ２１０７）。
【０１３５】
ステップＳ２１１２で取得したオペコードが呼び出し命令である場合（ステップＳ２２０４：Ｙｅｓ）、生成部１４０２は、取得した行に、取得したオペコードに対応するオペランドが存在するか否かを判定する（ステップＳ２２０５）。オペランドが存在しない場合（ステップＳ２２０５：Ｎｏ）、図２１のステップＳ２１０７に戻って、生成部１４０２は、次の行を取得する（ステップＳ２１０７）。
【０１３６】
オペランドが存在する場合（ステップＳ２２０５：Ｙｅｓ）、生成部１４０２は、オペランドがラベル名を参照するアドレスとなっているかを判定する（ステップＳ２２０６）。オペランドがラベル名を参照するアドレスとなっていない場合（ステップＳ２２０６：Ｎｏ）、図２１のステップＳ２１０７に戻って、生成部１４０２は、次の行を取得する（ステップＳ２１０７）。
【０１３７】
オペランドがラベル名を参照するアドレスとなっている場合（ステップＳ２２０６）、生成部１４０２は、ラベル名を文字列として、変数Ｖにセットする（ステップＳ２２０７）。つぎに、生成部１４０２は、変数Ｖにセットされたラベル名をキーとし、命令文情報格納テーブル１０００から、キーであるラベル名に一致する命令文１００１に対応するアノテーション属性１００２を検索するとともに、インターフェース情報格納テーブル１１００から、キーであるラベル名に一致するインターフェース１１０１に対応する属性１１０２を検索する（ステップＳ２２０８）。
【０１３８】
生成部１４０２は、検索したアノテーション属性１００２に含まれる属性と検索した属性１１０２とが一致するか否かを判断する（ステップＳ２２０９）。不一致である場合（ステップＳ２２０９：Ｎｏ）、図２１のステップＳ２１０２に戻る。一方、一致する場合（ステップＳ２２０９：Ｙｅｓ）、生成部１４０２は、一致した属性１１０２をキーとして、フィルタルール情報格納テーブル１３００から、対応するフィルタルール１３０２を検索する（ステップＳ２２１０）。そして、図２３のステップＳ２３０１に移行する。
【０１３９】
図２３において、生成部１４０２は、検索できたか否か判断する（ステップＳ２３０１）。検索できなかった場合（ステップＳ２３０１：Ｎｏ）、ステップＳ２３０５に移行する。検索できた場合（ステップＳ２３０１：Ｙｅｓ）、生成部１４０２は、検索されたフィルタルールによる処理を実行する（ステップＳ２３０２）。ステップＳ２３０２では、生成部１４０２は、スタックＳに格納された全命令文の呼び出し関係を判定する。フィルタルールによる処理を実行した結果、構文解析部１４０１は、取得した命令文がフィルタルールに適合するか否かを判定する（ステップＳ２３０３）。
【０１４０】
具体的には、生成部１４０２は、フィルタルールが属性違反を検出する関数であれば、属性違反であるか否かを判定し、フィルタルールが属性波及を検出する関数であれば、属性波及であるか否かを判定する。属性違反であったり属性波及である場合は、フィルタルールに適合することになる。
【０１４１】
フィルタルールに適合しない場合（ステップＳ２３０３：Ｎｏ）、ステップＳ２３０５に移行する。一方、フィルタルールに適合する場合（ステップＳ２３０３：Ｙｅｓ）、生成部１４０２は、フィルタルールに応じた制御処理を実行する（ステップＳ２３０４）。ここで、フィルタルールに応じた制御処理については、図１７のＳ１７１１で説明した内容と同一であるため、説明を省略する。そして、生成部１４０２は、変数Ｖにセットされたラベル名についてリンク処理をして（ステップＳ２３０５）、図２１のステップＳ２１０２に戻る。
【０１４２】
なお、依存関係抽出処理（ステップＳ２００６）は、構文解析部１４０１や生成部１４０２の実装に都合のよいように合わせて処理を変更してもよい。たとえば、命令文の呼び出し関係をアセンブラ言語の主プログラム、副プログラムの関係をもとに説明したが、本実施例では呼び出し命令のトレースができれば、アセンブラ言語にかぎらず機械語、バイトコード等のどのようなコードの呼び出し関係をトレースする実装でもよい。
【０１４３】
＜実行部１４０３による解析処理例＞
つぎに、実行部１４０３による解析処理例について説明する。実行部１４０３による解析処理では、解析対象として、プログラム２０７、３０１を解析する処理である。データを保存する方法としてスタックが用いられるが、必ずしもスタックである必要はなく、ヒープまたは静的なメモリ確保によるオンメモリでの処理を行う方法や、ファイルとして出力して保持して処理を行う方法を用いてもよい。
【０１４４】
図２４は、実行部１４０３による解析処理の詳細な処理手順例を示すフローチャートである。実行部１４０３は、プログラムのファイルをオープンする（ステップＳ２４０１）。つぎに、実行部１４０３は、プログラムの起動時にロードする他のプログラムのプログラム情報を、プログラム情報格納テーブル１２００に格納する（ステップＳ２４０２）。ステップＳ２４０２では、例えば、ステップＳ２４０１において実行部１４０３がオープンしたプログラムのファイルパスをプログラム情報格納テーブル１２００の呼び出し元１２０１に格納し、実行部１４０３がロードするプログラムのファイルパスを参照物１２０２に格納し、「実行時の構成要素」という文字列を呼び出し形態１２０３に格納する。
【０１４５】
つぎに、実行部１４０３は、インターフェース情報格納テーブル１１００を用いて、プログラムに含まれるインターフェース１１０１に対応する属性１１０２を検索する（ステップＳ２４０３）。そして、実行部１４０３は、フィルタルール情報格納テーブル１３００から、検索した属性１１０２に一致する属性１３０１に対応するフィルタルール１３０２を取得する（ステップＳ２４０４）。
【０１４６】
つぎに、実行部１４０３は、プログラムの開始位置を探索する（ステップＳ２４０５）。そして、実行部１４０３は、依存関係抽出処理を実行する（ステップＳ２４０６）。依存関係抽出処理を実行する（ステップＳ２４０６）の詳細については後述する。
【０１４７】
なお、依存関係抽出処理（ステップＳ２４０６）では、実行部１４０３がプログラムの実行中にロード処理を行う際に、オープンするプログラムのプログラム情報をプログラム情報格納テーブル１２００に格納してもよい。この際には例えば、実行部１４０３が実行中のプログラムのファイルパスをプログラム情報格納テーブル１２００の呼び出し元１２０１に格納し、新たにオープンしたプログラムのファイルパスを参照物１２０２に格納し、「実行時の構成要素」という文字列を呼び出し形態１２０３に格納する。
【０１４８】
依存関係抽出処理（ステップＳ２４０６）が終了した後は、実行部１４０３は、プログラムのファイルをクローズし（ステップＳ２４０７）、解析結果を生成して出力する（ステップＳ２４０８）。これにより、実行部１４０３は、依存関係抽出処理を終了する。解析結果とは、たとえば、図８に示した解析結果画面８０１である。また、属性違反がある場合には警告画面８２０を出力してもよい。
【０１４９】
＜依存関係抽出処理（ステップＳ２４０６）＞
図２５〜図２７は、図２４に示した依存関係抽出処理（ステップＳ２４０６）の詳細な処理手順例を示すフローチャート１〜３である。実行部１４０３は、プログラムを起動する際に、起動するプログラムのファイルパスを変数Ｐに格納する（ステップＳ２５０１）。つぎに、実行部１４０３は、変数Ｐが指すプログラムを読み込み、先頭の命令文を実行する（ステップＳ２５０２）。そして、実行部１４０３は、実行した命令文が、変数Ｐが指すプログラムにおける命令文の終端であるかを判定する（ステップＳ２５０３）。
【０１５０】
変数Ｐが指すプログラムにおける命令文の終端である場合（ステップＳ２５０３：Ｙｅｓ）、実行部１４０３は、プログラムの実行を終了し、例えば、図２４のステップＳ２４０７に移行する。変数Ｐが指すプログラムにおける命令文の終端でない場合（ステップＳ２５０３：Ｎｏ）、実行部１４０３は、実行した命令文からオペコードを取得し（ステップＳ２５０４）、オペコードが対象としているオペランドを取得する（ステップＳ２５０５）。
【０１５１】
実行した命令文がプログラムにおける命令文の終端を判断する材料としては、具体的には、例えば、プログラムを実行する実行ファイルまたはプロセッサ９０１のレジスタのプログラムカウンタのアドレス先がプログラムの終了処理を行うコードであるかを判定する方法がある。
【０１５２】
つぎに、実行部１４０３は、オペコードがリターン命令であるかを判定する（ステップＳ２５０６）。リターン命令でない場合（ステップＳ２５０６：Ｎｏ）、ステップＳ２５０７に移行し、リターン命令である場合（ステップＳ２５０６：Ｙｅｓ）、実行部１４０３は、スタックＦからシンボル名をポップする（ステップＳ２５０７）。
【０１５３】
つぎに、実行部１４０３は、ステップＳ２５０４で取得したオペコードが呼び出し命令であるかを判定する（ステップＳ２５０８）。呼び出し命令でない場合（ステップＳ２５０８：Ｎｏ）、次の命令を実行し（ステップＳ２５０９）、ステップＳ２５０３に戻る。呼び出し命令である場合（ステップＳ２５０８：Ｙｅｓ）、実行部１４０３は、ステップＳ２５０５で取得したオペランドが呼び出し先を示す値となっているかを判定する（ステップＳ２５１０）。オペランドが呼び出し先を示す値となっていない場合（ステップＳ２５１０：Ｎｏ）、ステップＳ２５０９に戻る。オペランドが呼び出し先を示す値となっている場合（ステップＳ２５１０：Ｙｅｓ）、実行部１４０３は、呼び出し先のアドレスを記憶し（ステップＳ２５１１）、プロセスのメモリマップを取得する（ステップＳ２５１２）。ここで、メモリマップについて説明する。
【０１５４】
図２８は、メモリマップの一例を示す説明図である。メモリマップとは、プログラムがメモリ上に展開されてプロセスとして実行している際、プロセスがメモリ上にロードするプログラムとメモリアドレスとを対応付けた記憶領域である。プロセスがメモリ上にロードするプログラムとは、例えば、ライブラリ等がある。プログラムがメモリに展開されてプロセスとして実行される際、プロセスのメモリマップは、例えば、ＯＳの機能により擬似ファイルとして出力される。したがって、通常のテキストファイルと同様にメモリマップを閲覧することが可能となる。また、プログラムの実行中に新たに他のプログラムをロードする場合、メモリマップ２８０１は、例えば、ＯＳの機能によって随時更新される。
【０１５５】
なお、メモリマップは必ずしもＯＳの機能によって出力されるものでなくてもよく、メモリマップの出力を行う機能と同等の機能を備えたプログラムや、専用のハードウェアによって出力してもよい。メモリマップ２８０１では、プログラム３０１である「ｍａｉｎ２.ｅｘｅ」がプロセスとしてメモリ上に展開された際のメモリマップの例を示している。メモリアドレスの範囲２８０３にはプログラム２８０４が対応している。プログラム２８０４〜２８０６のようにファイル名が同じでっても、メモリアドレスの範囲によって、例えば、メモリアドレスの読み書き権限や属性の違いがある場合、其々のメモリアドレスは区別されて出力される場合がある。なお、プログラム２８０７のように、起動されているプログラムである、例えば「ｍａｉｎ２.ｅｘｅ」自体もプロセスがロードしているプログラムとして扱われ、メモリマップ上に出力されることがある。
【０１５６】
図２５に戻り、実行部１４０３は、ステップＳ２５１１で記憶した呼び出し先のアドレスがプロセスのメモリマップに対応するアドレスか否かを判定する（ステップＳ２５１３）。ステップＳ２５１３の処理は、例えば、ステップＳ２５１１において記憶した呼び出し先のアドレスがメモリマップ２８０１のメモリアドレスの範囲２８０２のどの位置に存在しているかをチェックする処理である。例えば、ステップＳ２５１１において記憶した呼び出し先のアドレスの値が「００１１００４５」である場合、当該アドレスはメモリアドレスの範囲２８０３に存在し、そのアドレスに対応する呼び出し先のプログラムはプログラム２８０４（ファイルパスで指定されるプログラム）であり、プログラム２８０４の開始アドレスの値は「００１１００００」となる。
【０１５７】
プロセスのメモリマップに対応するアドレスが存在しない場合（ステップＳ２５１３：Ｎｏ）、ステップＳ２５０９に戻る。プロセスのメモリマップに対応するアドレスが存在する場合（ステップＳ２５１３：Ｙｅｓ）、図２６のステップＳ２６０１に移行する。
【０１５８】
図２６において、実行部１４０３は、ステップＳ２５１１において記憶した呼び出し先のアドレスの値から、ステップＳ２５１３において判定した呼び出し先のプログラムの開始アドレスの値を減算し、算出した値をオフセットアドレスとして記憶する（ステップＳ２６０１）。例えば、ステップＳ２５１１において記憶した呼び出し先のアドレスの値が「００１１００４５」であり、呼び出し先のプログラムの開始アドレスが「００１１００００」である場合、オフセットアドレスは「００００００４５」となる。
【０１５９】
つぎに、実行部１４０３は、アドレスに対応するプログラムのファイルパスを呼び出し先のプログラムとして、記憶デバイスに記憶する（ステップＳ２６０２）。つぎに、実行部１４０３は、呼び出し命令の呼び出し元のプログラム名をキーとして、ジャンプ先のプログラムのファイルパスを、プログラム情報格納テーブル１２００に格納する（ステップＳ２６０３）。ステップＳ２６０３では、例えば、ステップＳ２５０１または後述するステップＳ２６０９において変数Ｐに格納されたファイルパスをプログラム情報格納テーブル１２００の呼び出し元１２０１に格納し、ステップＳ２６０２において記憶した呼び出し先のプログラムのファイルパスを参照物１２０２に格納し、「実行時の読み込み要素」という文字列を呼び出し形態１２０３に格納する。
【０１６０】
つぎに、実行部１４０３は、呼び出し先のプログラムのシンボルテーブルが参照可能かを判定する（ステップＳ２６０４）。シンボルテーブルが参照可能でない場合（ステップＳ２６０４：Ｎｏ）、図２５のステップＳ２５０９に戻る。シンボルテーブルが参照可能である場合（ステップＳ２６０４：Ｙｅｓ）、実行部１４０３は、呼び出し先のプログラムのシンボルテーブルを取得する（ステップＳ２６０５）。ここで、シンボルテーブルについて説明する。
【０１６１】
図２９は、シンボルテーブルの一例を示す説明図である。シンボルテーブル２９００とは、プログラムがもつシンボルとシンボルのオフセットアドレスとを対応付けたテーブルである。シンボルとは、例えば、関数、変数、その他任意の値等に対応する名前である。実行部１４０３は、シンボルを検索することで、プログラム間をまたいで、関数、変数、その他任意の値等を呼び出すことが可能である。例えば、プログラムがライブラリの関数、変数、その他任意の値を利用する際にシンボルが用いられる。
【０１６２】
図２６に戻り、実行部１４０３は、呼び出し先のプログラムのオフセットアドレスに対応するシンボルがシンボルテーブル２９００にあるか否かを判定する（ステップＳ２６０６）。対応するシンボルがない場合（ステップＳ２６０６：Ｎｏ）、ステップＳ２５０９に戻る。対応するシンボルがある場合（ステップＳ２６０６：Ｙｅｓ）、実行部１４０３は、呼び出し先のシンボル名をシンボルテーブルから取得する（ステップＳ２６０７）。例えば、ステップＳ２６０１で記憶したオフセットアドレスの値が「００００００４５」である場合、シンボルテーブル２９００のメモリアドレス２９０６と一致する。したがって、ステップＳ２６０１で記憶したオフセットアドレスの値である「００００００４５」に対応するシンボルは、シンボル２９０５の「ｅｎｇｌｉｓｈ」となる。
【０１６３】
つぎに、実行部１４０３は、ステップＳ２６０７で取得した呼び出し先のシンボル名をスタックＦにプッシュし（ステップＳ２６０８）、呼び出し先のプログラムのファイルパスを変数Ｐに格納する（ステップＳ２６０９）。つぎに、実行部１４０３は、ステップＳ２６０７で取得した呼び出し先のシンボル名をキーとし、当該キーに一致する命令文１００１に対応するアノテーション属性１００２を命令文情報格納テーブル１０００から検索するとともに、当該キーに一致するインターフェース１１０１に対応する属性１１０２をインターフェース情報格納テーブル１１００から検索する（ステップＳ２６１０）。この後、図２７のステップＳ２７０１に移行する。
【０１６４】
図２７において、実行部１４０３は、検索したアノテーション属性１００２に含まれる属性と検索した属性１１０２とが一致するか否かを判断する（ステップＳ２７０１）。不一致である場合（ステップＳ２７０１：Ｎｏ）、図２５のステップＳ２５０９に戻る。一方、一致する場合（ステップＳ２７０１：Ｙｅｓ）、実行部１４０３は、一致した属性１１０２をキーとして、フィルタルール情報格納テーブル１３００から、対応するフィルタルール１３０２を検索する（ステップＳ２７０２）。
【０１６５】
つぎに、実行部１４０３は、検索できたか否か判断する（ステップＳ２７０３）。検索できなかった場合（ステップＳ２７０３：Ｎｏ）、図２５のステップＳ２５０９に戻る。検索できた場合（ステップＳ２７０３：Ｙｅｓ）、実行部１４０３は、検索されたフィルタルールによる処理を実行する（ステップＳ２７０４）。ステップＳ２７０４では、実行部１４０３は、スタックＦに格納された全シンボルである命令文の呼び出し関係を判定する。フィルタルールによる処理を実行した結果、実行部１４０３は、当該シンボルである命令文がフィルタルールに適合するか否かを判定する（ステップＳ２７０５）。
【０１６６】
具体的には、実行部１４０３は、フィルタルールが属性違反を検出する関数であれば、属性違反であるか否かを判定し、フィルタルールが属性波及を検出する関数であれば、属性波及であるか否かを判定する。属性違反であったり属性波及である場合は、フィルタルールに適合することになる。
【０１６７】
フィルタルールに適合しない場合（ステップＳ２７０５：Ｎｏ）、図２５のステップＳ２５０９に戻る。一方、フィルタルールに適合する場合（ステップＳ２７０５：Ｙｅｓ）、実行部１４０３は、フィルタルールに応じた制御処理を実行する（ステップＳ２７０６）。ここで、フィルタルールに応じた制御処理については、図１７のＳ１７１１で説明した内容と同一であるため、説明を省略する。このあと、図２５のステップＳ２５０９に戻る。
【０１６８】
なお、依存関係抽出処理（ステップＳ２４０６）は、プログラムを実行する実行部１４０３の実装に都合のよいように合わせて処理を変更してもよい。例では、命令文の呼び出し関係をＣＰＵ命令で説明したが、本実施例においては、呼び出し命令のトレースができれば、機械語、バイトコード等のどのようなコードの呼び出し関係をトレースする実装でもよい。また、実行部１４０３が解釈する言語も機械語でなくてもよい。
【０１６９】
以上に説明したように、本実施例によれば、プログラムリスト、中間ファイル、またはプログラムのいずれかである解析対象を解析して、開発者が意図しない命令文の依存関係を検出することができる。
【０１７０】
また、フィルタルールが命令文の呼び出し違反を検出するフィルタルールである場合、アノテーションとして規定した命令文が、意図しない命令文を呼び出していることを検出することができる。これにより、解析対象にライセンス違反となる命令文の呼び出しが含まれているかを把握することができる。
【０１７１】
また、意図しない命令文を呼び出していることを検出した場合、当該命令文や呼び出し元の命令文を示す情報（たとえば、図６〜図８を参照）を生成して出力することにより、開発者は、どの命令文が意図しない命令文を呼び出しているかを把握することができる。
【０１７２】
また、フィルタルールが属性の波及を検出するフィルタルールである場合、アノテーションとして規定した命令文の属性が、他の命令文に波及することを検出することができる。これにより、開発者はライセンス伝播や脆弱性の影響範囲を把握することができる。
【０１７３】
また、属性の波及を検出した場合、当該属性の波及元の命令文と波及先の命令文を示す情報を生成して出力することにより、開発者は、どの命令文の属性がどの命令文に波及しているかを把握することができる。
【０１７４】
また、プログラムリストを構文解析して構文解析木を作成することにより、プログラムリストに記載される命令文の記述の違いを吸収して、依存関係を判定することができる。したがって、記述の違いについて開発者は修正することなくプログラムリストを読み込ませることができ、開発者の負担軽減を図ることができる。
【０１７５】
また、プログラムリストから命令文情報格納テーブル１０００のエントリを作成することにより、フィルタルール群の中から該当するフィルタルールをディスパッチテーブルに格納しておくことで、適用されないフィルタルールを検索する必要がなくなるため、処理速度の向上を図ることができる。
【０１７６】
また、解析対象が中間ファイルである場合、対象となる行がニーモニックであるか否かを判定することにより、ニーモニックでない場合、中間ファイル５０１，５１６，５２０や中間ファイルのリンク相手となるプログラム５２４，５２８の中に記載されているコメントアウト等のテキストを読み飛ばすことができる。したがって、処理速度の向上を図ることができる。
【０１７７】
以上、本発明を添付の図面を参照して詳細に説明したが、本発明はこのような具体的構成に限定されるものではなく、添付した請求の範囲の趣旨内における様々な変更及び同等の構成を含むものである。
【符号の説明】
【０１７８】
９００  解析装置
１０００  命令文情報格納テーブル
１１００  インターフェース情報格納テーブル
１２００  プログラム情報格納テーブル
１３００  フィルタルール情報格納テーブル
１４０１  構文解析部
１４０２  生成部
１４０３  実行部
【図１】
2016122321.tif 000003
【図２】
2016122321.tif 000004
【図３】
2016122321.tif 000005
【図４】
2016122321.tif 000006
【図５】
2016122321.tif 000007
【図６】
2016122321.tif 000008
【図７】
2016122321.tif 000009
【図８】
2016122321.tif 000010
【図９】
2016122321.tif 000011
【図１０】
2016122321.tif 000012
【図１１】
2016122321.tif 000013
【図１２】
2016122321.tif 000014
【図１３】
2016122321.tif 000015
【図１４】
2016122321.tif 000016
【図１５】
2016122321.tif 000017
【図１６】
2016122321.tif 000018
【図１７】
2016122321.tif 000019
【図１８】
2016122321.tif 000020
【図１９】
2016122321.tif 000021
【図２０】
2016122321.tif 000022
【図２１】
2016122321.tif 000023
【図２２】
2016122321.tif 000024
【図２３】
2016122321.tif 000025
【図２４】
2016122321.tif 000026
【図２５】
2016122321.tif 000027
【図２６】
2016122321.tif 000028
【図２７】
2016122321.tif 000029
【図２８】
2016122321.tif 000030
【図２９】
2016122321.tif 000031