図1は、コンパイル装置を含む情報処理システムの一例を示す図である。
情報処理システムは、生成装置1と、コンパイル装置3と、実行装置5とを含む。生成装置1は、ユーザがコンパイル処理対象のソースプログラム2を生成するコンピュータである。コンパイル装置3は、ソースプログラム2をコンパイル処理することにより、実行プログラム4を生成するコンピュータである。実行プログラム4は、ソースプログラム2の実行形式のプログラムである。実行装置5は、実行プログラム4を実行することにより、プログラム実行結果出力6を得るコンピュータである。プログラム実行結果出力6は、実行プログラム4を実行した結果である。
生成装置1は、例えばネットワークを介して、生成したソースプログラム2をコンパイル装置3に送信する。コンパイル装置3は、受信したソースプログラム2を記憶装置に格納し、格納したソースプログラム2を読み出してコンパイル処理して、実行プログラム4を生成する。
コンパイル装置3は、生成した実行プログラム4を記憶装置に格納し、格納した実行プログラム4を読み出して、例えばネットワークを介して、読み出した実行プログラム4を実行装置5に送信する。実行装置5は、受信した実行プログラム4を記憶装置に格納し、格納した実行プログラム4を読み出して実行する。
コンパイル装置3は、コンパイラ31と、リンカ38と、ライブラリ39とを含む。コンパイラ31は、構文意味解析部32と、最適化部35と、コード生成部36とを含む。コンパイラ31は、ソースプログラム2に基づいて、構造化データ33と、中間プログラム34と、オブジェクトプログラム37とを生成する。
コンパイル装置3のコンパイラ31において、構文意味解析部32は、ソースプログラム2を記憶装置から読み出し、中間プログラム34の生成に先立って、ソースプログラム2を解析することにより、構造化データ33を生成する。具体的には、構文意味解析部32は、ソースプログラム2についての構文解析処理及び意味解析処理を実行することにより、構造化データ33を生成する。構造化データ33は、コンパイル装置3以外のコンピュータにより生成されて、コンパイル装置3に入力されるようにしても良い。構造化データ33は、記憶装置に格納される。
ユーザにより作成されたソースプログラム2は、例えば、コーディング入力された複数のソースコードと、1又は複数の組込みデバッグ指示行21とを含む。組込みデバッグ指示行21は、デバッグ情報の出力指示である。具体的には、組込みデバッグ指示行21は、ユーザによって記述されることでソースプログラム2に組込まれたコードであって、デバッグ情報の収集及び出力を指示するコードである。組込みデバッグ指示行21は、ソースコードとは異なるコードであり、ソースコードとしては通常用いられないコードであって、予め定められる。デバッグ情報の収集及び出力は、実際には、実行プログラム4を実行する実行装置5に対して指示される。換言すれば、実際のデバッグ情報の収集及び出力は、実行装置5が実行プログラム4を実行することにより実行される。
構文意味解析部32は、ソースプログラム2を解析することにより、中間プログラム34を生成する第1の生成部である。具体的には、構文意味解析部32は、ソースプログラム2についての構文解析処理及び意味解析処理を実行することにより、中間プログラム34を生成する。中間プログラム34は中間コードで記述される。従って、構文意味解析部32は、中間コードを生成するコード生成処理を実行するコード生成部を含む。中間プログラム34は、記憶装置に格納される。中間プログラム34は、ソースプログラム2から生成されるプログラムであると言う観点からは、実行プログラムの一形態であると考えることもできる。
なお、実際には、1回の構文解析処理及び意味解析処理により、構造化データ33及び中間プログラム34が生成される。換言すれば、構造化データ33が構文解析処理に基づいて生成されるようにしても良い。
中間プログラム34の生成において、構文意味解析部32は、ソースプログラム2に組込みデバッグ指示行21が含まれる場合に、組込みデバッグ指示行21に対応するデバッグ情報出力命令341を含む中間プログラム34を生成する。デバッグ情報出力命令341は、ソースプログラム2の構造を表す構造化データ33に基づいて、組込みデバッグ指示行21が指示する出力対象であるプログラム要素、換言すれば、組込みデバッグ指示行21が指示するプログラム要素を解析することにより生成される。デバッグ情報出力命令341は、デバッグ情報を出力させる命令であり、中間コードで記述される。プログラム要素は、例えば、後述するように、デバッグ対象である文又は式、デバッグ対象である文又は式において使用されている変数又は関数、デバッグ対象である関数、デバッグ対象である関数における仮引数、デバッグ対象である外部変数又は静的変数等である。
最適化部35は、中間プログラム34を最適化処理して、最適化処理により得られた最適化された中間プログラム34を、コード生成部36に渡す。中間プログラム34がデバッグ情報出力命令341を含む場合、デバッグ情報出力命令341も最適化される。
コード生成部36は、最適化された中間プログラム34に基づいてオブジェクトコードを生成することにより、オブジェクトプログラム37を生成する。オブジェクトプログラム37はオブジェクトコードで記述される。中間プログラム34がデバッグ情報出力命令341を含む場合、オブジェクトプログラム37は、デバッグ情報出力命令371を含む。デバッグ情報出力命令371は、デバッグ情報を出力させる命令であり、最適化されたデバッグ情報出力命令341に基づいて生成される。
リンカ38は、オブジェクトプログラム37と、オブジェクトプログラム37において指定されたライブラリ39とをリンクすることにより、実行プログラム4を生成する。実行プログラム4は、実行可能なコードで記述された実行形式のプログラムである。オブジェクトプログラム37がデバッグ情報出力命令371を含む場合、実行プログラム4は、デバッグ情報出力命令41を含む。デバッグ情報出力命令41は、デバッグ情報出力命令371に基づいて生成される。換言すれば、ソースプログラム2が組込みデバッグ指示行21を含む場合、実行プログラム4は、組込みデバッグ指示行21に基づいて生成されたデバッグ情報出力命令41を含む。
デバッグ情報出力命令41は、デバッグ情報の収集及び出力を指示する命令であるが、デバッガで実行されることはなく、実行装置5において実行される。換言すれば、デバッグ情報出力命令41は、実行装置5に対して、デバッグ情報の収集及び出力、換言すれば、デバッグ及びデバッグ結果の出力を指示する命令である。組込みデバッグ指示行21は、デバッグ情報出力命令41、換言すれば、実行装置5に対するデバッグ情報の収集及び出力を指示する命令を生成する命令である。また、デバッグ情報出力命令41の実行により、デバッグ及びデバッグ結果が出力される。出力されたデバッグ及びデバッグ結果に基づいて、実行プログラムが実際に実行可能なものか否かが判定される。従って、デバッグ情報出力命令41は、実行プログラムの実行可否を判定する命令であると言うことができる。
以上のように、デバッグ情報出力命令41を含む実行プログラム4が、中間プログラム34から生成される。換言すれば、最適化部35、コード生成部36、リンカ38が、中間プログラム34に基づいて、実行プログラム4を生成する第2の生成部である。
実行装置5は、実行プログラム4を実行することにより、実行プログラム4のプログラム実行結果出力6を得る。実行装置5は、実行プログラム4の実行において、デバッグ情報出力命令41を、デバッグ情報の収集及び出力であることを意識することなく、他の命令と同様に実行する。
実行プログラム4がデバッグ情報出力命令41を含む場合、プログラム実行結果出力6は、デバッグ情報出力61を含む。デバッグ情報出力61を除くプログラム実行結果出力6は、実行プログラム4のデバッグ情報出力命令41を除く部分を実行した結果である。デバッグ情報出力61は、実行プログラム4における予め定められた1又は複数の部分をデバッグした結果である。
以上のように、実行装置5は、実行プログラム4を実行することにより、実行プログラム4のプログラム実行結果出力6と、デバッグ情報出力命令41を実行することにより得られる実行プログラム4のデバッグ情報出力61とを生成する。
プログラム実行結果出力6は、例えば1個のファイルとして出力される。デバッグ情報出力61を、プログラム実行結果出力6のファイルとは独立の別のファイルに出力するようにしても良い。
図2は、組込みデバッグ指示行の一例を示す図である。
組込みデバッグ指示行21としては、図2(A)に示すように、プラグマ指令「#pragma」が用いられる。プラグマ指令は、C++言語の規格及びC言語の規格において、各々、規定されている指令であり、コンパイラに渡される指令である。従って、プラグマ指令を用いることにより、ソースプログラム2に影響を与えることなく、コンパイラ31の動作を制御することができる。
組込みデバッグ指示行21には、図2(A)に示すように、「statement」「parameter」「global」の3種類がある。これにより、ソースプログラム2の殆ど全てのプログラム要素についてのデバッグ情報の収集及び出力を指示することができる。
種類が「statement」である組込みデバッグ指示行21は、ユーザが文や式で使われている変数や関数についてのデバッグ情報を出力したい場合に用いられる。換言すれば、種類が「statement」である組込みデバッグ指示行21は、デバッグしたい、換言すれば、デバッグ対象である文又は式を指定し、指定された文又は式において使用されている変数又は関数についてのデバッグを指示する命令である。
組込みデバッグ指示行21の種類が「statement」である場合、構文意味解析部32は、組込みデバッグ指示行21に対応するデバッグ情報出力命令341として、指定された文又は式において使用されている変数又は関数をソースプログラム2から抽出し、抽出した変数又は関数についての情報を収集する命令を生成する。
デバッグ情報出力命令341に基づいて生成されるデバッグ情報出力命令371及びデバッグ情報出力命令41も、デバッグ情報出力命令341と同様の命令である。組込みデバッグ指示行21の種類が「parameter」又は「global」である場合も同様である。
種類が「statement」である組込みデバッグ指示行21は、図2(A)に示すように、例えば、「#pragma builtin_debug statement [変数並び]」のような形式で記述される。組込みデバッグ指示行「#pragma builtin_debug statement [変数並び]」は、例えば、デバッグ対象である文又は式の直前に組み込まれる。これにより、デバッグ対象である文又は式、更には、デバッグ対象である文又は式に記述されている変数や関数が指定される。組込みデバッグ指示行「#pragma builtin_debug statement [変数並び]」から生成されたデバッグ情報出力命令41により、指定した文又は式に記述されている変数や関数の情報が、ソースプログラム2から収集され、デバッグ情報として出力される。
例えば、ソースプログラム2がC++言語で記述されている場合、メンバ関数、コンストラクタ、オペレータ関数、テンプレート関数の情報が、収集されデバッグ情報として出力される。組込みデバッグ指示行「#pragma builtin_debug statement [変数並び]」がブロック文を指定する場合には、指定されたブロック文内に含まれる1又は複数の文又は1又は複数の式で使用されている全ての変数及び関数等のデバッグ情報が出力される。
種類が「parameter」である組込みデバッグ指示行21は、ユーザが関数の仮引数についてのデバッグ情報を出力したい場合に用いられる。換言すれば、種類が「parameter」である組込みデバッグ指示行21は、デバッグ対象である関数を指定し、指定された関数における仮引数についてのデバッグを指示する命令である。
組込みデバッグ指示行21の種類が「parameter」である場合、構文意味解析部32は、組込みデバッグ指示行21に対応するデバッグ情報出力命令341として、指定された関数における仮引数をソースプログラム2から抽出し、抽出した仮引数についての情報を収集する命令を生成する。
種類が「parameter」である組込みデバッグ指示行21は、図2(A)に示すように、例えば、「#pragma builtin_debug parameter [変数並び]」のような形式で記述される。組込みデバッグ指示行「#pragma builtin_debug parameter [変数並び]」は、例えば、デバッグ対象である関数の先頭に組み込まれる。これにより、デバッグ対象である関数、更には、デバッグ対象である関数における仮引数が指定される。組込みデバッグ指示行「#pragma builtin_debug parameter [変数並び]」から生成されたデバッグ情報出力命令41により、仮引数の情報が収集され、デバッグ情報として出力される。
種類が「global」である組込みデバッグ指示行21は、ユーザが外部変数又は静的変数についてのデバッグ情報を出力したい場合に用いられる。換言すれば、種類が「global」である組込みデバッグ指示行21は、デバッグ対象である外部変数又は静的変数を指定し、指定された外部変数又は静的変数についてのデバッグを指示する命令である。
組込みデバッグ指示行21の種類が「global」である場合、構文意味解析部32は、組込みデバッグ指示行21に対応するデバッグ情報出力命令341として、指定された外部変数又は静的変数をソースプログラム2から抽出し、抽出した外部変数又は静的変数についての情報を収集する命令を生成する。
種類が「global」である組込みデバッグ指示行21は、図2(A)に示すように、例えば、「#pragma builtin_debug global [変数並び]」のような形式で記述される。組込みデバッグ指示行「#pragma builtin_debug global [変数並び]」は、例えば、組み込まれた位置から可視の外部変数又は静的変数を指定する。組込みデバッグ指示行「#pragma builtin_debug global [変数並び]」よりも前の行で宣言されている変数は、コンパイラ31に対して可視になっている。これにより、デバッグ対象である可視の外部変数又は静的変数が指定される。組込みデバッグ指示行「#pragma builtin_debug global [変数並び]」から生成されたデバッグ情報出力命令41により、組み込まれた位置から可視の外部変数又は静的変数が収集され、デバッグ情報として出力される。
組込みデバッグ指示行21においては、図2(B)に示すように、「変数並び」を指定することができる。「変数並び」においては、1個の識別子により、変数が指定される。又は、「変数並び」においては、変数を指定する1個の識別子に続けて、更に、「変数並び」を記述することができる。これにより、複数の変数を指定することができる。
「変数並び」が指定されている場合には、実行装置5による組込みデバッグ指示行21から生成されたデバッグ情報出力命令41の実行により、「変数並び」により指定された変数のデバッグ情報のみが生成される。「変数並び」の指定は、省略することができる。「変数並び」が指定されていない場合には、実行装置5による組込みデバッグ指示行21から生成されたデバッグ情報出力命令41の実行により、組込みデバッグ指示行21の組み込まれた位置により定まる変数や関数等のデバッグ情報が生成される。
例えば、種類が「statement」である組込みデバッグ指示行21において「変数並び」が指定されている場合には、「変数並び」において指定された変数又は関数のデバッグ情報のみが出力される。種類が「parameter」である組込みデバッグ指示行21において「変数並び」が指定されている場合には、「変数並び」において指定された仮引数のデバッグ情報のみが出力される。種類が「global」である組込みデバッグ指示行21において「変数並び」が指定されている場合には、「変数並び」において指定された外部変数又は静的変数のデバッグ情報のみが出力される。
なお、実際には、いずれの種類の組込みデバッグ指示行21においても、以上に述べたデバッグ情報に加えて、ファイル名、カレントの関数名、行番号が、共に出力される。ファイル名、カレントの関数名、行番号は、出力しないようにしても良い。
図3は、ソースプログラムの一例を示す図である。
例えば、ソースプログラム2は、高級プログラム言語、例えばオブジェクト指向言語であるC++言語又はC言語により記述される。また、例えば、ソースプログラム2は、3種類の組込みデバッグ指示行21を含む。具体的には、19行目、24行目、27行目に、各々、組込みデバッグ指示行21を含む。このように、組込みデバッグ指示行21をソースプログラム2に埋め込むことができるので、ソースプログラム2を把握している開発者が容易に使用することができ、また、組込みデバッグ指示行21をルートテスト用としても使用することができる。
図3に示すように、1個のソースプログラム2に含まれる組込みデバッグ指示行21の数は、1個であっても良く、複数個であっても良い。組込みデバッグ指示行21の数は、デバッグ対象の数に応じて定まる。
なお、図3のソースプログラム2において、左端の数字は、ソースプログラム2における行数を表す。また、ソースプログラム2の名前は、例えば「sample.cc」である。
組込みデバッグ指示行21は、予め定められたコンパイル装置3において実行される命令であって、予め定められたコンパイル装置3以外のコンパイル装置においてはエラーを発生せずかつ実行されない命令である。具体的には、組込みデバッグ指示行21としてプラグマ指令「#pragma」を使用することにより、ソースプログラム2の可搬性を保障することができる。換言すれば、ソースプログラム2は、コンパイラ31以外のコンパイラでコンパイルされても、エラーを発生しない。
組込みデバッグ指示行21は、ソースプログラム2において、デバッグ対象である文又は式を指定する位置であって文又は式に対して予め定められた関係にある位置、デバッグ対象である関数を指定する位置であって関数に対して予め定められた関係にある位置、又は、デバッグ対象である外部変数又は静的変数を指定する位置であって外部変数又は静的変数に対して予め定められた関係にある位置に含まれる。組込みデバッグ指示行21の位置については後述する。
従って、ソースプログラム2において、組込みデバッグ指示行21の記述される位置、換言すれば、組込みデバッグ指示行21が組込まれる位置は、ソースプログラム2のコーディングの際に、ユーザにより定められる。換言すれば、組込みデバッグ指示行21が組込まれる位置は、ユーザによりデバッグ対象の部分の位置に応じて定められる。これにより、ユーザは、ソースプログラム2において、自分がデバッグ対象とした箇所のみを、デバッグすることができる。
19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」は、種類が「parameter」の組込みデバッグ指示行21である。種類が「parameter」の組込みデバッグ指示行21は、前述したように、デバッグ対象である関数を指定し、指定された関数における仮引数についてのデバッグを指示する。一方、19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」は、17行目から始まる関数funcにおいて、先頭の位置に指定されている。従って、19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」は、17行目の関数funcを指定し、関数funcの仮引数paramのデバッグを指示するデバッグ情報出力命令であると言うことができる。
24行目の組込みデバッグ指示行「#pragma builtin_debug global」は、種類が「global」の組込みデバッグ指示行21である。種類が「global」の組込みデバッグ指示行21は、前述したように、デバッグ対象である外部変数又は静的変数を指定し、指定された外部変数又は静的変数についてのデバッグを指示する。一方、24行目の組込みデバッグ指示行「#pragma builtin_debug global」からは、2行目の「int data=10」及び5行目の「int data=20」が可視である。従って、24行目の組込みデバッグ指示行「#pragma builtin_debug global」は、ソースプログラム2に含まれる可視の外部変数又は静的変数である2行目の「data=10」及び5行目の「data=20」のデバッグを指示するデバッグ情報出力命令であると言うことができる。
27行目の組込みデバッグ指示行「#pragma builtin_debug statement」は、種類が「statement」の組込みデバッグ指示行21である。種類が「statement」の組込みデバッグ指示行21は、前述したように、デバッグ対象である文又は式を指定し、指定された文又は式において使用されている変数又は関数についてのデバッグを指示する。一方、27行目の組込みデバッグ指示行「#pragma builtin_debug statement」は、28行目の「ret = clsobj+data;」の直前に組み込まれている。従って、27行目の組込みデバッグ指示行「#pragma builtin_debug statement」は、28行目の「ret = clsobj+data;」のデバッグを指示するデバッグ情報出力命令であると言うことができる。
以上のように、コンパイラ31の構文意味解析部32がデバッグ情報を出力するためのコードを生成するため、ユーザは、デバッグ用のソースプログラム2をコーディングしたりコンパイルする必要がない。また、ソースプログラム2が変更された結果、デバッグ対象の変数等が増加した場合に、ユーザは、ソースプログラム2を再度コーディングする必要がなく、ソースプログラム2をリコンパイルするだけで、デバッグ対象の増加に対応したデバッグ情報を出力することができる。更に、コンパイル可能なソースプログラム2であれば、どのようなソースプログラム2でも、どのような文又は式でも、デバッグ情報を出力することができる。
図4は、構造化データの一例を示す図である。
コンパイラ31の構文意味解析部32は、構文解析処理に基づいて、図3に示すソースプログラム2から、図4に示す構造化データ33を生成する。
具体的には、構文意味解析部32は、ソースプログラム2の名前「sample.cc」に基づいて、「sample.cc」というコンパイルの単位「CompileUnit」を抽出する。「CompileUnit」は、ソースプログラム2のデータ構造における最上位の階層である。
更に、構文意味解析部32は、「CompileUnit」の1つ下位の階層として、名前空間、クラス等のタイプ、using文、関数等を抽出する。
具体的には、「CompileUnit」の1つ下位の階層として、最初に、1行目の「namespace NS1 {」と3行目の「};」とに基づいて、「NS1」という「Namespace」が抽出される。
更に、構文意味解析部32は、「Namespace」の1つ下位の階層として、変数等を抽出する。具体的には、2行目の「int data=10;」は、「NS1」という「Namespace」内に「{}」で囲まれている。従って、「int data=10;」に基づいて、「NS1」という「Namespace」の1つ下位の階層として、「data=10」という「Variable」が抽出される。
同様に、「CompileUnit」の1つ下位の階層として、4行目の「namespace NS2 {」と6行目の「};」とに基づいて、「NS2」という「Namespace」が抽出される。また、5行目の「int data=20;」に基づいて、「NS2」という「Namespace」の1つ下位の階層として、「data=20」という「Variable」が抽出される。
次に、「CompileUnit」の1つ下位の階層として、8行目の「class CLS {」と13行目の「};」とに基づいて、「CLS」という「Type」が抽出される。
更に、構文意味解析部32は、クラス等の「Type」の1つ下位の階層として、変数等を抽出する。具体的には、10行目の「int mem;」、及び、11行目の「int operator + (int i) ....;」は、「CLS」という「Type」内に「{}」で囲まれている。従って、10行目の「int mem;」に基づいて、「CLS」という「Type」の1つ下位の階層として、「mem」という「Member」が抽出される。また、11行目の「int operator + (int i) ....;」に基づいて、「CLS」という「Type」の1つ下位の階層として、「operator + (int)」という「Member」が抽出される。なお、10行目と11行目は、クラスにおけるデータメンバ又はメンバ関数であり、階層構造として抽出される。また、9行目と12行目は、クラスにおけるキーワード等であり、階層構造として抽出されず、無視される。
次に、「CompileUnit」の1つ下位の階層として、15行目の「using namespace NS1;」に基づいて、「NS1」という「using namespace」が抽出される。
次に、「CompileUnit」の1つ下位の階層として、17行目の「int func(int param)」、18行目の「{」及び31行目の「}」に基づいて、「func(int)」という「Function」が抽出される。19行目〜31行目は、「func(int)」という「Function」内に「{}」で囲まれている。従って、19行目〜31行目は、「func(int)」という「Function」の下位の階層として抽出される。
更に、構文意味解析部32は、関数の1つ下位の階層として、パラメータ、プラグマ指令、変数、文又は式等を抽出する。
具体的には、「func(int)」という「Function」内において、17行目の「int func(int param)」に基づいて、「func(int)」という「Function」の1つ下位の階層として、「param」という「Parameter」が抽出される。また、19行目の「#pragma builtin_debug parameter」に基づいて、「func(int)」という「Function」の1つ下位の階層として、「builtin_debug parameter」という「Pragma」が抽出される。従って、プラグマ指令は、関数Function内において、データ構造という観点からはパラメータや変数と同列である。
また、21行目の「CLS clsobj;」に基づいて、「func(int)」という「Function」の1つ下位の階層として、「clsobj」という「Variable」が抽出される。また、22行目の「int ret=0;」に基づいて、「func(int)」という「Function」の1つ下位の階層として、「ret」という「Variable」が抽出される。また、24行目の「#pragma builtin_debug global」に基づいて、「func(int)」という「Function」の1つ下位の階層として、「builtin_debug global」という「Pragma」が抽出される。
また、26行目の「if (param && data) {」と29行目の「}」とに基づいて、「func(int)」という「Function」の1つ下位の階層として、「if (param && data)」という「Statement」が抽出される。27行目〜28行目は、「if (param && data)」という「Statement」内に「{}」で囲まれている。従って、27行目〜28行目は、「if (param && data)」という「Statement」の下位の階層として抽出される。
更に、「if (param && data)」という「Statement」内において、28行目の「ret=clsobj+data;」に基づいて、「if (param && data)」という「Statement」の1つ下位の階層として、「ret=clsobj+data」という「Statement」が抽出される。
また、27行目の「#pragma builtin_debug statement」に基づいて、「builtin_debug statement」という「Pragma」が抽出される。27行目の「#pragma builtin_debug statement」は、28行目の「ret=clsobj+data;」についてのデバッグ指示行であるので、28行目の1つ下位の階層とされる。従って、27行目と28行目とでは、行の位置の上下と階層の上下とが逆転している。
更に、構文意味解析部32は、ソースプログラム2がオブジェクト指向言語であるので、各階層の間における関連を抽出し、抽出した階層の間を関連付ける。
具体的には、28行目から生成された階層「ret=clsobj+data;」に含まれる「ret」は、同一の名前を持つので、22行目から生成された「ret」である。そこで、28行目から生成された階層に含まれる「ret」が22行目から生成された「ret」であることを構造的に表現するために、図4に点線で示すように、28行目から生成された階層に含まれる「ret」と22行目から生成された「ret」とが関連付けられる。同様に、28行目から生成された階層に含まれる「clsobj」と21行目から生成された「clsobj」とが、図4に点線で示すように、関連付けられる。
また、28行目から生成された階層に含まれる「+」は、加算を定義する演算子である。クラスにおいて加算に関連するデータメンバ又はメンバ関数は、11行目から生成された「operator + (int)」である。そこで、28行目から生成された階層に含まれる「+」と11行目から生成された「operator + (int)」とが、図4に点線で示すように、関連付けられる。
また、15行目のusing文において「NS1」という「Namespace」を使用することを宣言しているので、28行目から生成された階層に含まれる「data」は、「NS1」という「Namespace」における「data=10」という「Variable」、換言すれば、2行目から生成された「data=10」である。そこで、28行目から生成された階層に含まれる「data」と2行目から生成された「data=10」とが、図4に点線で示すように、関連付けられる。
以上のような構文意味解析部32による構文解析処理により、図3に示すソースプログラム2から、図4に示す構造化データ33が得られる。
図5は、デバッグ情報出力の一例を示す図である。
実行装置5は、図3に示すソースプログラム2から生成された実行プログラム4を実行して、図5に示すプログラム実行結果出力6を得る。プログラム実行結果出力6は、デバッグ情報出力61を含む。
プログラム実行結果出力6において、1行目〜2行目は、実行プログラム4のデバッグ情報出力命令41を除く部分を実行した結果である。3行目〜12行目は、デバッグ情報出力61であり、デバッグ情報出力命令41を実行した結果である。
プログラム実行結果出力6において、実行プログラム4の実行時におけるデバッグ情報出力61の出力の有無は、環境変数、換言すれば、フラグにより制御される。フラグの値は、例えば、ソースプログラム2の生成時に、ユーザにより例えばソースプログラム2において指定される。なお、ソースプログラム2のコンパイル処理に先立って、フラグの値を指定するようにしても良い。
構文意味解析部32は、フラグの値が「0」である場合には、ソースプログラム2に含まれた組込みデバッグ指示行21をコンパイルしない。従って、中間プログラム34にはデバッグ情報出力命令341が含まれず、実行プログラム4にはデバッグ情報出力命令41が含まれず、実行装置5によりデバッグ情報出力61が出力されない。構文意味解析部32は、フラグの値が「1」である場合には、ソースプログラム2に含まれた組込みデバッグ指示行21をコンパイルする。従って、中間プログラム34にはデバッグ情報出力命令341が含まれ、実行プログラム4にはデバッグ情報出力命令41が含まれ、実行装置5によりデバッグ情報出力61が出力される。
これにより、実行プログラム4の実行時に、デバッグ情報の出力の有無を制御することができる。従って、デバッグ用のコードである組込みデバッグ指示行21を含んだままのソースプログラム2を、フラグの値を「1」から「0」に変更するのみで実際の運用において使用することができ、また、運用時における実行速度への影響も少なくすることができる。
フラグの値は、例えば、プログラム実行結果出力6において、1行目の最後尾に出力される。図5においては、フラグの値が「1」であるので、プログラム実行結果出力6がデバッグ情報出力61を含む状態で出力される。これにより、ユーザは、プログラム実行結果出力6に含まれるプログラム実行結果出力6以外の部分がデバッグ情報出力61であるか否かを知り、また、デバッグの結果を知ることができる。
プログラム実行結果出力6の2行目には、プログラム実行結果出力6の出力先のファイルの名前が出力される。換言すれば、実行プログラム4のデバッグ情報出力命令41を除く部分を実行した結果は、「a.out」というファイルに出力される。
構文意味解析部32は、組込みデバッグ指示行21を解析する第1の解析処理を実行し、組込みデバッグ指示行21の指示対象を解析する第2の解析処理を実行し、第1及び第2の解析処理に基づいてデバッグ情報出力命令341を生成する。
例えば、デバッグ情報出力61において、3行目〜4行目は、ソースプログラム2における19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」から生成されたデバッグ情報出力命令41を実行した結果である。具体的には、ソースプログラム2の17行目の関数funcの仮引数paramのデバッグ情報が出力される。
構文意味解析部32は、組込みデバッグ指示行「#pragma builtin_debug parameter」が、19行目に記述されていることを解析し、更に、この解析に基づいて、図3を参照して前述したように、17行目の関数funcを指定し、関数funcの仮引数paramのデバッグを指示することを解析する。
そこで、以上の解析に基づいて、構文意味解析部32は、19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」から、17行目の関数funcの仮引数paramについての全ての情報をソースプログラム2の内部から収集して出力するデバッグ情報出力命令341を生成する。これにより、実行プログラム4には、17行目の関数funcの仮引数paramについての情報を収集して出力するデバッグ情報出力命令41が含まれる。
実行装置5は、19行目の組込みデバッグ指示行「#pragma builtin_debug parameter」から生成されたデバッグ情報出力命令41を実行することにより、17行目の関数funcの仮引数paramについての情報を収集して、デバッグ情報として出力する。
次に、デバッグ情報出力61において、5行目〜7行目は、ソースプログラム2における24行目の組込みデバッグ指示行「#pragma builtin_debug global」から生成されたデバッグ情報出力命令41を実行した結果である。具体的には、ソースプログラム2の2行目及び5行目の可視の外部変数又は静的変数「data=10」及び「data=10」のデバッグ情報が出力される。
構文意味解析部32は、組込みデバッグ指示行「#pragma builtin_debug global」が、24行目に記述されていることを解析し、更に、この解析に基づいて、図3を参照して前述したように、可視の外部変数又は静的変数である2行目の「data=10」及び5行目の「data=10」のデバッグを指示する命令であることを解析する。
そこで、以上の解析に基づいて、構文意味解析部32は、24行目の組込みデバッグ指示行「#pragma builtin_debug global」から、2行目及び5行目の可視の外部変数又は静的変数「data=10」及び「data=10」についての全ての情報をソースプログラム2の内部から収集して出力するデバッグ情報出力命令341を生成する。これにより、実行プログラム4には、2行目及び5行目の可視の外部変数又は静的変数「data=10」及び「data=10」についての情報を収集して出力するデバッグ情報出力命令41が含まれる。
実行装置5は、24行目の組込みデバッグ指示行「#pragma builtin_debug global」から生成されたデバッグ情報出力命令41を実行することにより、2行目及び5行目の可視の外部変数又は静的変数「data=10」及び「data=10」についての情報を収集して、デバッグ情報として出力する。
次に、デバッグ情報出力61において、8行目〜12行目は、ソースプログラム2における27行目の組込みデバッグ指示行「#pragma builtin_debug statement」から生成されたデバッグ情報出力命令41を実行した結果である。具体的には、ソースプログラム2の28行目の「ret = clsobj+data;」のデバッグ情報が出力される。
構文意味解析部32は、組込みデバッグ指示行「#pragma builtin_debug statement」が、27行目に記述されていることを解析し、更に、この解析に基づいて、図3を参照して前述したように、28行目の「ret = clsobj+data;」のデバッグを指示する命令であることを解析する。
そこで、以上の解析に基づいて、構文意味解析部32は、27行目の組込みデバッグ指示行「#pragma builtin_debug statement」から、28行目の「ret = clsobj+data;」についての全ての情報をソースプログラム2の内部から収集して出力するデバッグ情報出力命令341を生成する。これにより、実行プログラム4には、28行目の「ret = clsobj+data;」についての情報を収集して出力するデバッグ情報出力命令41が含まれる。
デバッグ情報出力命令341の生成において、構文意味解析部32は、更に、構造化データ33を参照する。これにより、構文意味解析部32は、デバッグ対象である「ret = clsobj+data;」が、2行目の変数「data」、11行目のオペレータ関数「CLS::operator +(int)」、21行目の変数「clsobj」、22行目の変数「ret」に、各々、関連付けられていることを知る。そこで、構文意味解析部32は、デバッグ情報出力命令341として、単に28行目の「ret = clsobj+data;」の情報を収集して出力するのみでなく、これに加えて、変数「ret」、変数「clsobj」、変数「data」、オペレータ関数「CLS::operator +(int)」についての情報を収集して出力する命令を生成する。
実行装置5は、27行目の組込みデバッグ指示行「#pragma builtin_debug statement」から生成されたデバッグ情報出力命令41を実行することにより、28行目の「ret = clsobj+data;」についての情報を収集して、デバッグ情報として出力する。
この時、ソースプログラム2の28行目の「ret = clsobj+data;」において使用されている、変数「clsobj」、変数「ret」、変数「data」のデバッグ情報が出力される。ここで、変数「clsobj」は、クラス型のためクラス名を表示している。また、変数「data」は、「NS1」という「Namespace」と「NS2」という「Namespace」の双方で定義されているが、15行目のusing文により 「NS1」という「Namespace」で定義されているdataが参照されていることを表している。12行目の「CLS::operator +(int)」は、CLSクラスで宣言されたオペレータ関数が使用されたことを表している。これは、「clsobj+data」の加算演算が、実際には、オペレータ関数「CLS::operator +(int)」が使用されている、換言すれば、呼び出されているためである。
なお、ソースプログラム2に含まれる複数の組込みデバッグ指示行21の中で、特定の組込みデバッグ指示行21に基づくデバッグ情報のみを出力するようにしても良い。この場合、例えば、制御用関数インタフェースが設けられ、その関数内において、例えば、「char builtin_debug_table[]={“test.c:17”, “test.c:26”};のように、ファイル名と行番号が規定の配列の初期値として指定される。これにより、特定の組込みデバッグ指示行21についてのデバッグ情報のみを出力することができる。
以上のように、実行装置5がデバッグ情報出力命令41を実行することによりデバッグ情報を出力するので、デバッグ用の外部ツールやデバッグ用のライブラリ等を何ら用いることなく、デバッグ情報を収集し出力することができる。また、コンパイル装置3がデバッグ情報出力命令41を生成するので、ユーザは、デバッグ情報出力命令41をコーディングする必要がない。
また、例えば、ソースプログラム2がC++言語で記述されたプログラムである場合、ユーザは、識別子解決結果、関数のオーバーロード/オーバーライドの解決結果、ソースプログラム2において記述された式のコンパイラ31における解析結果や解決結果を、デバッグ情報として知ることができる。例えば、識別子解決結果は、どのネームスペースの識別子を参照したのかを示す。関数のオーバーロード/オーバーライドの解決結果は、例えばオペレータ演算子を含む。ソースプログラム2において記述された式は、例えばテンプレート関数等を含む。
図6は、コンパイル装置のハードウェアの構成の一例を示す図である。
CPU101は、ROM102に格納された制御プログラムに従って、コンパイル装置3を制御する。CPU101は、例えば主メモリであるRAM103上のコンパイルプログラムを実行する。これにより、コンパイラ31及びリンカ38が実現される。コンパイルプログラムは、例えば、CD−ROMやDVD等の記録媒体109に格納され、記録媒体109からハードディスク106に入力され、ハードディスク106からCD−ROMドライブやDVDドライブ等を介してRAM103にロードされる。
プログラム及びデータ格納部は、例えばハードディスク106に設けられ、ソースプログラム2、構造化データ33、中間プログラム34、オブジェクトプログラム37、ライブラリ39、実行プログラム4を格納する。換言すれば、プログラム及びデータは、例えばハードディスク106に格納される。ライブラリ39は、例えば、CD−ROMやDVD等の記録媒体109に格納され、記録媒体109からCD−ROMドライブやDVDドライブ等を介してハードディスク106に入力され、必要に応じてハードディスク106からRAM103にロードされ、リンカ38により処理される。構造化データ33、中間プログラム34、オブジェクトプログラム37、実行プログラム4は、コンパイラ31又はリンカ38により生成される。
入力装置104は、例えばキーボードであり、マウス等を含んでも良い。出力装置105は、例えばディスプレイであり、プリンタ等の出力装置を含んでも良い。CPU101、ROM102、RAM103、入力装置104、出力装置105、及び、ハードディスク106、ネットワーク接続部107は、バス108を介して、相互に接続される。
ネットワーク接続部107は、例えば、送受信装置であり、ネットワークに接続され、ネットワークを介して他のコンピュータ、例えば生成装置1及び実行装置5に接続される。これにより、コンパイル装置3は、生成装置1及び実行装置5との間で通信を行う。ソースプログラム2は、例えば、生成装置1からネットワークを介してハードディスク106に入力され、必要に応じてハードディスク106からRAM103にロードされ、コンパイラ31及びリンカ38により処理される。実行プログラム4は、コンパイル装置3からネットワークを介して実行装置5に送信され実行される。
図7は、コンパイラ31が実行するコンパイル処理フローであって、特に、ソースプログラムからデバッグ情報出力命令を含む中間プログラムを生成する処理フローを示す。
コンパイル装置3において、コンパイラ31がソースプログラム2を読込むと(ステップS1)、構文意味解析部32が、読み込まれたソースプログラム2の字句解析処理を実行し(ステップS2)、字句解析処理の結果に基づいて、読み込まれたソースプログラム2の構文解析処理及び意味解析処理を実行する(ステップS3)。構文解析処理及び意味解析処理により、ソースプログラム2の構造化データ33が生成される。
構文意味解析部32は、ソースプログラム2の先頭から順に1行ずつコードを抽出し、抽出した行において組込みデバッグ指示行21が指定されているか否かを判断する(ステップS4)。組込みデバッグ指示行21が指定されていない場合には(ステップS4 No)、構文意味解析部32は、ステップS3を繰り返す。
組込みデバッグ指示行21が指定されている場合には(ステップS4 Yes)、構文意味解析部32は、組込みデバッグ指示行21の種類が「statement」であるか、「parameter」 であるか、「global」であるかを判断する(ステップS5)。
次に、構文意味解析部32は、組込みデバッグ指示行21において「変数並び」が指定されているか否かを判断し、更に、指定されている場合には、その変数が宣言されているか否かを検査する(ステップS6)。
一方、ステップS6において、組込みデバッグ指示行21において「変数並び」が指定されていない場合は、構文意味解析部32は、組込みデバッグ指示行21が指定された位置に基づいて、ソースプログラム2において指定されている変数や関数を調べる(ステップS7)。
次に、構文意味解析部32は、変数や関数のデバッグ情報を収集し出力するための命令を生成し、併せてファイル名、関数名、行番号の情報出力命令も生成する(ステップS8)。
次に、構文意味解析部32は、図5に示す環境変数、換言すれば、フラグを判定条件として用いて、組込みデバッグ指示行21の中間コードであるデバッグ情報出力命令341を生成する(ステップS9)。
次に、構文意味解析部32は、ソースプログラム2における全ての行の処理を終了したか否かを判断する(ステップS10)。全ての行の処理を終了していない場合には(ステップS10 No)、構文意味解析部32は、ステップS3を繰り返す。全ての行の処理を終了した場合には(ステップS10 Yes)、構文意味解析部32は、処理を終了する。
以上の説明から理解されるように、以下のような実施の態様が把握される。
(付記1) コンパイル処理対象のソースプログラムにデバッグ情報の出力指示が含まれる場合に、前記ソースプログラムの構造を表す構造化データに基づいて、前記出力指示の出力対象であるプログラム要素を解析することにより生成したデバッグ情報を出力させる命令を含む実行プログラムを生成する第1の生成部と、
前記ソースプログラムのコンパイル処理結果として、前記実行プログラムの実行可否を判定する命令を含む実行プログラムを生成する第2の生成部とを含む
ことを特徴とするコンパイル装置。
(付記2) 前記第1の生成部は、前記出力指示を解析する第1の解析処理を実行し、前記出力指示の指示対象を解析する第2の解析処理を実行し、前記第1及び第2の解析処理に基づいて前記デバッグ情報出力命令を生成する
ことを特徴とする付記1に記載のコンパイル装置。
(付記3) 前記第1の生成部は、前記実行プログラムの生成に先立って、前記ソースプログラムを解析することにより、前記構造化データを生成する
ことを特徴とする付記1に記載のコンパイル装置。
(付記4) 前記出力指示は、予め定められたコンパイル装置において実行される命令であって、前記予め定められたコンパイル装置以外のコンパイル装置においてはエラーを発生せずかつ実行されない命令である
ことを特徴とする付記1に記載のコンパイル装置。
(付記5) 前記出力指示は、前記ソースプログラムにおいて、デバッグ対象である文又は式を指定する位置であって前記文又は式に対して予め定められた関係にある位置、デバッグ対象である関数を指定する位置であって前記関数に対して予め定められた関係にある位置、又は、デバッグ対象である外部変数又は静的変数を指定する位置であって前記外部変数又は静的変数に対して予め定められた関係にある位置に含まれる
ことを特徴とする付記1に記載のコンパイル装置。
(付記6) 前記出力指示は、デバッグ対象である文又は式を指定し、指定された前記文又は式において使用されている変数又は関数についてのデバッグを指示する命令である
ことを特徴とする付記5に記載のコンパイル装置。
(付記7) 前記第1の生成部は、前記出力指示に対応する前記デバッグ情報出力命令として、前記ソースプログラムから指定された前記文又は式において使用されている変数又は関数を抽出し、抽出した前記変数又は関数についての情報を収集する命令を生成する
ことを特徴とする付記6に記載のコンパイル装置。
(付記8) 前記出力指示は、デバッグ対象である関数を指定し、指定された前記関数における仮引数についてのデバッグを指示する命令である
ことを特徴とする付記5に記載のコンパイル装置。
(付記9) 前記第1の生成部は、前記出力指示に対応する前記デバッグ情報出力命令として、前記ソースプログラムから指定された前記関数における仮引数を抽出し、抽出した前記仮引数についての情報を収集する命令を生成する
ことを特徴とする付記8に記載のコンパイル装置。
(付記10) 前記出力指示は、デバッグ対象である外部変数又は静的変数を指定し、指定された前記外部変数又は静的変数についてのデバッグを指示する命令である
ことを特徴とする付記5に記載のコンパイル装置。
(付記11) 前記第1の生成部は、前記出力指示に対応する前記デバッグ情報出力命令として、前記ソースプログラムから指定された前記外部変数又は静的変数を抽出し、抽出した前記外部変数又は静的変数についての情報を収集する命令を生成する
ことを特徴とする付記10に記載のコンパイル装置。
(付記12) 前記ソースプログラムは、オブジェクト指向言語であるC++言語又はC言語により記述され、前記出力指示は、前記C++言語の規格及びC言語においてコンパイラに渡される指令として規定されているプラグマ指令である
ことを特徴とする付記1に記載のコンパイル装置。
(付記13) ソースプログラムをコンパイル処理することにより実行プログラムを生成するコンパイル装置と、
前記実行プログラムを実行する実行装置とを含む情報処理システムであって、
前記コンパイル装置は、
コンパイル処理対象のソースプログラムにデバッグ情報の出力指示が含まれる場合に、前記ソースプログラムの構造を表す構造化データに基づいて、前記出力指示の出力対象であるプログラム要素を解析することにより生成したデバッグ情報を出力させる命令を含む実行プログラムを生成する第1の生成部と、
前記ソースプログラムのコンパイル処理結果として、前記実行プログラムの実行可否を判定する命令を含む実行プログラムを生成する第2の生成部とを含み
前記実行装置は、前記実行プログラムを実行することにより、前記実行プログラムの実行結果と、前記デバッグ情報出力命令を実行することにより得られる前記実行プログラムのデバッグ情報とを生成する
ことを特徴とする情報処理システム。
(付記14) コンパイル処理対象のソースプログラムにデバッグ情報の出力指示が含まれる場合に、前記ソースプログラムの構造を表す構造化データに基づいて、前記出力指示の出力対象であるプログラム要素を解析することにより生成したデバッグ情報を出力させる命令を含む実行プログラムを生成し、
前記ソースプログラムのコンパイル処理結果として、前記実行プログラムの実行可否を判定する命令を含む実行プログラムを生成する
ことを特徴とするコンパイル方法。
(付記15) ソースプログラムをコンパイル処理することにより実行プログラムを生成するコンパイルプログラムであって、
前記コンパイルプログラムは、コンピュータに、
コンパイル処理対象のソースプログラムにデバッグ情報の出力指示が含まれる場合に、前記ソースプログラムの構造を表す構造化データに基づいて、前記出力指示の出力対象であるプログラム要素を解析することにより生成したデバッグ情報を出力させる命令を含む実行プログラムを生成する第1の生成処理と、
前記ソースプログラムのコンパイル処理結果として、前記実行プログラムの実行可否を判定する命令を含む実行プログラムを生成する第2の生成処理とを実行させる
ことを特徴とするコンパイルプログラム。
(付記16) ソースプログラムをコンパイル処理することにより実行プログラムを生成するコンパイルプログラムを記録する記録媒体であって、
前記コンパイルプログラムは、コンピュータに、
コンパイル処理対象のソースプログラムにデバッグ情報の出力指示が含まれる場合に、前記ソースプログラムの構造を表す構造化データに基づいて、前記出力指示の出力対象であるプログラム要素を解析することにより生成したデバッグ情報を出力させる命令を含む実行プログラムを生成する第1の生成処理と、
前記ソースプログラムのコンパイル処理結果として、前記実行プログラムの実行可否を判定する命令を含む実行プログラムを生成する第2の生成処理とを実行させる
ことを特徴とする記録媒体。