(57)【特許請求の範囲】
【請求項１】
コンピュータに、マクロ定義およびマクロ呼び出しを含む第１のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行わせて第２のソースコードを出力させるためのプリプロセッサと、
前記コンピュータに、前記プリプロセッサを用いて出力された前記第２のソースコードに対して、字句解析によってトークンに分割させてトークン配列を出力させるためのレキサと、
前記コンピュータに、前記レキサを用いて出力された前記トークン配列に基づいて構文解析を行わせ、抽象構文木を生成させるためのパーサとを有するソース解析プログラムであって、
前記コンピュータは、
前記プリプロセッサを用いて前記第１のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第１のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第２のソースコードとして出力し、
前記レキサを用いて前記トークン配列を出力する際に、前記プリプロセッサを用いて出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、
前記パーサを用いて前記抽象構文木を生成する際に、前記レキサを用いて生成された前記トークンを含んでノードを構成することを特徴とするソース解析プログラム。
【請求項２】
請求項１に記載のソース解析プログラムにおいて、
前記拡張文字に係る前記文字種別は、前記第１のソースコードにおける文字がそのまま対応する通常文字と、マクロ展開によって展開された前記マクロ定義に係る文字であるマクロ文字と、マクロ展開によって展開された前記マクロ定義の前および後に挿入される前記特殊文字であるマクロ開始文字およびマクロ終了文字を含み、
前記コンピュータは、前記プリプロセッサを用いて、前記通常文字に係る前記位置情報として、前記第１のソースコードにおける対応する文字の位置を設定し、前記マクロ文字に係る前記位置情報については設定せず、前記マクロ開始文字および前記マクロ終了文字に係る前記位置情報としては、それぞれ前記第１のソースコードにおける対応する前記マクロ定義に係る前記マクロ呼び出しの開始位置および終了位置を設定することを特徴とするソース解析プログラム。
【請求項３】
請求項２に記載のソース解析プログラムにおいて、
前記コンピュータは、前記レキサを用いて、前記第２のソースコードに対して、字句解析によって前記トークンに分割する際に、前記マクロ開始文字については、後続の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにし、前記マクロ終了文字については、先行の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにすることを特徴とするソース解析プログラム。
【請求項４】
請求項２または３に記載のソース解析プログラムにおいて、
さらに、前記コンピュータに、前記パーサを用いて出力された前記抽象構文木を参照して解析を行わせることにより、前記第１のソースコードの記述内容についての解析を行わせるための解析部を有し、
前記コンピュータは、前記解析部を用いて、前記抽象構文木の各ノードに含まれる前記トークンに対応する前記拡張文字の文字列に基づいて、前記各ノードに対応する前記第１のソースコードにおける位置の情報を識別することを特徴とするソース解析プログラム。
【請求項５】
請求項４に記載のソース解析プログラムにおいて、
前記コンピュータは、前記解析部を用いて、前記拡張文字の文字列に対応する前記第１のソースコードにおける位置の情報を、前記拡張文字の文字列に含まれる全ての要素に係る前記拡張文字の前記位置情報によって特定される範囲の和に基づいて識別し、
前記要素は、前記マクロ開始文字と前記マクロ終了文字の最外部の組、もしくは前記組の間に含まれない前記通常文字であることを特徴とするソース解析プログラム。
【請求項６】
コンピュータに、マクロ定義およびマクロ呼び出しを含む第１のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行わせて第２のソースコードを出力させるためのプリプロセッサであって、
前記コンピュータは、前記プリプロセッサを用いて前記第１のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第１のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第２のソースコードとして出力し、
前記拡張文字に係る前記文字種別は、前記第１のソースコードにおける文字がそのまま対応する通常文字と、マクロ展開によって展開された前記マクロ定義に係る文字であるマクロ文字と、マクロ展開によって展開された前記マクロ定義の前および後に挿入される前記特殊文字であるマクロ開始文字およびマクロ終了文字を含み、
前記コンピュータは、前記プリプロセッサを用いて、前記通常文字に係る前記位置情報として、前記第１のソースコードにおける対応する文字の位置を設定し、前記マクロ文字に係る前記位置情報については設定せず、前記マクロ開始文字および前記マクロ終了文字に係る前記位置情報としては、それぞれ前記第１のソースコードにおける対応する前記マクロ定義に係る前記マクロ呼び出しの開始位置および終了位置を設定することを特徴とするプリプロセッサ。
【請求項７】
請求項６に記載のプリプロセッサを用いて出力された前記第２のソースコードに対して、前記コンピュータに、字句解析によってトークンに分割してトークン配列を出力させるためのレキサであって、
前記コンピュータは、前記レキサを用いて前記トークン配列を出力する際に、前記プリプロセッサによって出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、
前記マクロ開始文字については、後続の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにし、前記マクロ終了文字については、先行の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにすることを特徴とするレキサ。
【請求項８】
請求項２または３のいずれか１項に記載のソース解析プログラムによって出力された前記抽象構文木を参照して解析を行わせることにより、前記コンピュータに、前記第１のソースコードの記述内容についての解析を行わせるための構文木解析プログラムであって、
前記コンピュータに、前記抽象構文木の各ノードに含まれる前記トークンに対応する前記拡張文字の文字列に基づいて、前記各ノードに対応する前記第１のソースコードにおける位置の情報を識別させることを特徴とする構文木解析プログラム。
【請求項９】
請求項８に記載の構文木解析プログラムにおいて、
前記コンピュータは、前記拡張文字の文字列に対応する前記第１のソースコードにおける位置の情報を、前記拡張文字の文字列に含まれる全ての要素に係る前記拡張文字の前記位置情報によって特定される範囲の和に基づいて識別し、
前記要素は、前記マクロ開始文字と前記マクロ終了文字の最外部の組、もしくは前記組の間に含まれない前記通常文字であることを特徴とする構文木解析プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラミング言語などによって記述されたソースコードに対する構文解析の技術に関し、特に、ソースコードに対してマクロ展開を行った後に字句解析、構文解析を行うソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムに適用して有効な技術に関するものである。
【背景技術】
【０００２】
プログラミング言語やタグ言語などによって記述されたソース（以下では「ソースコード」と記載する）に対して、コンパイラやコードチェックツールなどといったプログラムにおいて、ソースコードの内容を把握したり、ソースコードが文法や規則通りに記述されているか否かを判別したりするために構文解析が行われる。
【０００３】
このとき、一般的には、まずプリプロセッサによる前処理によって、ソースコードやヘッダファイルなどに定義されているマクロ定義を呼び出している箇所（マクロ呼び出し）が展開される。その後、マクロ展開後のソースコードに対してレキサによる字句解析、パーサによる構文解析が行われ、ＡＳＴ（Abstract Syntax Tree：抽象構文木）が生成される。その後、ＡＳＴに対して解析等を行い、その結果、文法が誤っているなどの箇所がある場合には、例えば、「ソースコード中のＸＸ行目のＹＹＹでエラーがある」などの指摘がされる。
【０００４】
しかし、字句解析や構文解析は、プリプロセッサによってマクロ呼び出しが展開された後のソースコードに対して行われるため、「ソースコードのＸＸ行目のＹＹＹ」といった情報もマクロ展開後のソースコードに対するものとなってしまう。従って、例えば、複数行に及ぶマクロ定義がある場合や、「ＹＹＹ」という命令がマクロ展開によって生成されたものである場合などでは、マクロ展開後のソースコードにおける「ＸＸ行目のＹＹＹ」という情報からマクロ展開前のソースコードにおける該当箇所を特定することが困難となる場合がある。
【０００５】
これに対し、プリプロセッサによる前処理を行った後も展開前のマクロ呼び出しの情報がなくならないようにする技術として、例えば、特開２００７−２６５０９５号公報（特許文献１）には、前処理指令の実行段階でのマクロ呼び出しの展開において、その展開前にマクロ展開前を示す文字と、マクロの展開後にマクロ展開後を示す文字とを埋め込むソースプログラム検証プログラムが記載されている。
【０００６】
また、非特許文献１には、プリプロセッサによる前処理前のＣ言語で記載されたソースコードに追跡子を埋め込み、これを観測することで、既存のプリプロセッサを利用して、前処理前後におけるマクロ展開のマッピング情報を得る技術が記載されている。
【先行技術文献】
【特許文献】
【０００７】
【特許文献１】特開２００７−２６５０９５号公報
【非特許文献】
【０００８】
【非特許文献１】権藤克彦他、「ソフトウェア工学の基礎１３  日本ソフトウェア科学会ＦＯＳＥ  ２００６」、株式会社近代科学社、２００６年１１月、ｐ９−１８（“ＴＢＣｐｐＡ：追跡子を用いたＣ前処理系解析器”）
【発明の概要】
【発明が解決しようとする課題】
【０００９】
従来技術では、プリプロセッサによる前処理を行う前のソースコードと、前処理を行ってマクロを展開した後のソースコードとの間でマクロ情報を維持してマッピングすることが可能である。すなわち、マクロ展開後のソースコードからマッピング情報に基づいてマクロ展開前のソースコードの内容（マクロ呼び出し）を復元することが可能である。
【００１０】
しかしながら従来技術では、プリプロセッサによってマクロ展開した後のソースコードに対して、さらに字句解析・構文解析を行ってＡＳＴを生成し、ＡＳＴに対して解析等を行う場合に、解析等によって検出したエラー等の箇所について、マクロ展開前のソースコード中のマクロ呼び出しにおける正確な位置情報を特定することが困難であったり、煩雑であったりする場合がある。
【００１１】
例えば、図７に示すようなマクロ定義とマクロ呼び出しを含むＣ言語で記載されたソースコードがある場合に、３行目の命令は、プリプロセッサによるマクロ展開によって“ＮＮ”のマクロ呼び出しが“１０”に展開され、さらに、“ＭＵＬ（１０，２０）”のマクロ呼び出しが“１０＊２０”に展開される。このとき、マクロ展開後のソースコードの命令文“ａ＝１０＊２０；”において、同じ“１０”を左端とするトークンでも、“１０”を対象とする場合と、“１０＊２０”を対象とする場合とでは、マクロ展開前のソースコードにおける対応するマクロ呼び出しが異なる（“ＮＮ”および“ＭＵＬ（ＮＮ，２０）”）。従って、図中の下線部に示すように、マクロ展開前のソースコードにおける位置情報についてもこれを考慮して対応するマクロ呼び出しの部分を正しく示す必要がある。
【００１２】
しかしながら、従来技術では、ＡＳＴの木構造とマクロ展開前のソースコードとの間でのマクロ情報の維持については考慮されておらずマッピング情報を有さないため、エラー等を有するＡＳＴのノード（図７の例における“１０”や“１０＊２０”）に対応する、マクロ展開前のソースコード中のマクロ呼び出しにおける正確な位置情報（範囲）を容易に特定することは困難である。特に、“１０＊２０”のような、複数のトークンの結合からなるノードについては、単に各トークン（“１０”、“＊”、“２０”）についての対応する位置をそれぞれ把握するだけでは、マクロ呼び出しにおける正確な位置情報（“ＭＵＬ（ＮＮ，２０）”の全体）を特定することは困難である。
【００１３】
また、例えば、非特許文献１に記載されたような技術では、複雑な多段展開のマクロについて正しくマッピング情報を得ることができなかったり、追跡子を埋め込むことによってソースコードのサイズの増大が非常に大きくなったりなど、効率的に利用するには制限がある場合もある。
【００１４】
そこで本発明の目的は、プリプロセッサによるマクロ展開後のソースコードに対する字句解析・構文解析によって得られるＡＳＴのノードに対しても、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を効率よく識別することを可能とするソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムを提供することにある。
【００１５】
本発明の前記ならびにその他の目的と新規な特徴は、本明細書の記述および添付図面から明らかになるであろう。
【課題を解決するための手段】
【００１６】
本願において開示される発明のうち、代表的なものの概要を簡単に説明すれば、以下のとおりである。
【００１７】
本発明の代表的な実施の形態によるソース解析プログラムは、マクロ定義およびマクロ呼び出しを含む第１のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行って第２のソースコードを出力するプリプロセッサと、前記プリプロセッサによって出力された前記第２のソースコードに対して、字句解析によってトークンに分割してトークン配列を出力するレキサと、前記レキサによって出力された前記トークン配列に基づいて構文解析を行い、抽象構文木を生成するパーサとを有するソース解析プログラムであって、以下の特徴を有するものである。
【００１８】
すなわち、前記プリプロセッサは、前記第１のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第１のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第２のソースコードとして出力し、前記レキサは、前記トークン配列を出力する際に、前記プリプロセッサによって出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、前記パーサは、前記抽象構文木を生成する際に、前記レキサによって生成された前記トークンを含んでノードを構成することを特徴とする。
【発明の効果】
【００１９】
本願において開示される発明のうち、代表的なものによって得られる効果を簡単に説明すれば以下のとおりである。
【００２０】
本発明の代表的な実施の形態によれば、プリプロセッサによるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字を挿入し、さらに各文字についてデータ構造として位置情報を保持する。この位置情報を字句解析によって得られるトークンに埋め込むことにより、構文解析によって得られるＡＳＴについても、ノードに含まれるトークンを介して、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を効率よく識別することが可能となる。
【図面の簡単な説明】
【００２１】
【図１】本発明の一実施の形態であるソース解析プログラムの構成例の概要について示した図である。
【図２】本発明の一実施の形態におけるプリプロセッサでのマクロ展開の処理の例について概要を示したフローチャートである。
【図３】本発明の一実施の形態におけるプリプロセッサによって出力された拡張文字配列内の文字における位置情報の設定および識別の例について説明する図である。
【図４】本発明の一実施の形態におけるプリプロセッサによって出力された拡張文字配列内の文字列における位置情報の識別の例について説明する図である。
【図５】本発明の一実施の形態における拡張文字配列内の文字列が、対応するソースコード中の位置情報を有さない場合の例を示した図である。
【図６】本発明の一実施の形態におけるプリプロセッサによって出力されたトークン配列、およびＡＳＴのノードにおける位置情報の識別の例について説明する図である。
【図７】トークンに応じてマクロ展開前のソースコード中のマクロ呼び出しにおける位置情報を特定する場合の例を示した図である。
【発明を実施するための形態】
【００２２】
以下、本発明の実施の形態を図面に基づいて詳細に説明する。なお、実施の形態を説明するための全図において、同一部には原則として同一の符号を付し、その繰り返しの説明は省略する。
【００２３】
本発明の一実施の形態であるソース解析プログラムは、マクロ定義およびマクロ呼び出しを含むソースコードに対して、プリプロセッサによるマクロ展開を行った後に字句解析、構文解析を行ってＡＳＴを生成し、ＡＳＴに対して解析（例えば、文書構造についての意味的な解析や、所定の文法や記述ルール、規約などに沿っているか否かのチェックなど）を行うことでソースコードの記述内容についての解析などを行うソフトウェアプログラムである。
【００２４】
本実施の形態のソース解析プログラムは、プリプロセッサによるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字を挿入し、さらに各文字についてデータ構造として位置情報を保持する。さらに、この位置情報を字句解析によって得られるトークンに埋め込むことにより、構文解析によって得られるＡＳＴについても、ノードに含まれるトークンを介して、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を容易に識別することを可能とするものである。
【００２５】
［プログラム構成］
図１は、本発明の一実施の形態であるソース解析プログラムの構成例の概要について示した図である。ソース解析プログラム１は、例えば、プリプロセッサ１０、レキサ２０、パーサ３０、および解析部４０の各プログラムを有し、ソースコード２を入力としてその記述内容についての解析を行うソフトウェアプログラムである。
【００２６】
このソース解析プログラム１は、例えば、コンパイラやコードチェックツール、文書解析プログラムなど、ソースコード２の文書構造を解析する処理を含む種々のプログラムの一部、または全部として実装される。従って、入力となるソースコードについても、Ｃ言語などのプログラミング言語やＸＭＬ（eXtensible Markup Language）などのタグ言語によって記述されたものに限らず、マクロ定義およびマクロ呼び出しを有するものであれば適用可能である。また、ソースコード２は複数のファイルから構成されていてもよく、例えば、マクロ定義を有するヘッダファイルなどを含んでいてもよい。
【００２７】
プリプロセッサ１０は、ソースコード２に対して、マクロ呼び出しをマクロ定義によって展開するマクロ展開を含む前処理を行って、前処理後のソースコード２を出力するソフトウェアプログラムである。本実施の形態のプリプロセッサ１０は、一般的なプリプロセッサと同様に、ソースコード２の文字を読み込んで、マクロ展開を行った後に文字配列としてソースコード２を出力するが、さらに、マクロ呼び出しをマクロ定義によって展開する際に、展開したマクロ定義の前後に特殊文字１１１を挿入する。これにより、マクロ展開によって生成された範囲が識別可能となるようにする。
【００２８】
また、文字配列を出力する際に、各文字を、単なる文字データではなくソースコード２上での位置情報１１２（例えば行、カラム）と、文字種別（通常文字、マクロ展開によって生成されたマクロ文字、および特殊文字の区分）の情報を含むデータ構造からなる拡張文字とし、拡張文字からなる拡張文字配列１１０として出力する。拡張文字のデータ構造は上記のものに限定されず、例えば、さらにマクロ展開後のソースコード２上での位置情報などを有していてもよい。また、拡張文字の実装方法についても特に限定されず、Ｃ言語における構造体や、オブジェクト指向言語におけるクラス、タプルなど種々の方法で実装することができる。プリプロセッサ１０での処理および拡張文字配列１１０の詳細については後述する。
【００２９】
レキサ２０は、プリプロセッサ１０によってマクロ展開を含む前処理が行われたソースコード２（すなわち拡張文字配列１１０）を入力として、字句解析を行うソフトウェアプログラムである。本実施の形態のレキサ２０は、マクロ展開後のソースコード２（拡張文字配列１１０）を字句解析によってトークンに分割（トークン化）し、トークン配列１２０を出力する。このとき、拡張文字配列１１０におけるトークンに対応する拡張文字の情報（特に位置情報１１２）がトークンに埋め込まれる。なお、字句解析の技術等については一般的なレキサ（もしくはトークナイザ、字句解析器など）におけるものと同様であるため説明は省略する。
【００３０】
パーサ３０は、レキサ２０によって出力されたトークン配列１２０に基づいて構文解析を行い、ＡＳＴ１３０を生成するソフトウェアプログラムである。なお、構文解析の技術やＡＳＴ１３０の構造等については、一般的なパーサ（もしくは構文解析器など）におけるものと同様であるため説明は省略する。
【００３１】
解析部４０は、パーサ３０によって出力されたＡＳＴ１３０を参照して解析等を行うことにより、ソースコード２の記述内容についての解析を行うソフトウェアプログラムである。このとき、ＡＳＴ１３０の各ノードに対応するトークン配列１２０中のトークンに対応する拡張文字の文字列（特に特殊文字１１１）、および拡張文字の位置情報１１２を参照することで、ＡＳＴ１３０の各ノードに対応するマクロ呼び出しを含むソースコード２での正確な位置情報を識別することができる。位置情報の識別方法の詳細については後述する。
【００３２】
解析部４０としては、例えば、コンパイラにおいてＡＳＴ１３０に対して意味解析を行ってオブジェクトコードを生成するコード生成部や、コードチェックツールにおいてコード作成規約・ルール等とのマッチングなどによりソースコードの記述内容をチェックするチェックロジックなどが該当する。なお、ＡＳＴ１３０の各ノードに対応するソースコード２での位置情報の識別に係る部分以外の解析等の技術（例えば、意味解析や最適化、ルールや規約とのマッチング等）については、コンパイラやコードチェックツール等における一般的なものと同様であるため説明は省略する。
【００３３】
［プリプロセッサでの処理フロー］
図２は、プリプロセッサ１０でのマクロ展開の処理の例について概要を示したフローチャートである。ソースコード２を入力して処理を開始すると、まず、ソースコード２の各文字を切り出して文字配列を生成する（Ｓ１０１）。次に、ソースコード２の文字配列に対して字句解析を行ってトークンを切り出し、トークン列を生成する（Ｓ１０２）。ここでは、一般的に正規表現などレキサ２０による字句解析と同等の技術を用いて文字配列をトークンに分割する。このとき、各トークンにはソースコード２における位置（例えば、開始・終了位置）および文字種別の情報を別途保持する。
【００３４】
その後、トークン列内の各トークンを対象として処理を繰り返すループ処理を開始する（Ｓ１０３）。ループ処理では、トークン列の先頭から処理対象のトークンをマクロ展開用のバッファに読み込む（Ｓ１０４）。このとき、バッファ内にトークンが存在する場合は後端に連結する形で読み込む。なお、当該バッファは、プリプロセッサ１０がマクロ展開処理時にプリプロセッサ１０が動作するコンピュータシステムのメモリ上に設けるデータ領域である。
【００３５】
次に、バッファ内のトークンがマクロ定義に該当する部分であるか否かを判定する（Ｓ１０５）。マクロ定義に該当する部分である場合は、バッファ内のトークンがマクロ定義として完結しているか否かを判定する（Ｓ１０６）。マクロ定義として完結している場合には、バッファ内のトークンの内容（マクロ定義）をマクロテーブルに出力し（Ｓ１０７）、バッファをクリアする。なお、マクロテーブルに出力したトークンの内容（マクロ定義）について、後の解析において利用するために、後述するステップＳ１０９の処理と同様に拡張文字として出力してもよい。
【００３６】
ステップＳ１０６においてバッファ内のトークンがマクロ定義として完結していない場合は、次のトークンの処理に移る（Ｓ１１４、Ｓ１０３）。なお、ソースコード２においてマクロ定義はマクロ呼び出しよりも前に記述されている必要があるため、通常は、以降のマクロ展開の処理が実行される前に、上記の処理によってマクロテーブルにマクロ定義が保持されることになる。
【００３７】
ステップＳ１０５においてバッファ内のトークンがマクロ定義に該当しない場合は、次に、バッファ内のトークンがマクロ呼び出しに該当する部分であるか否か、すなわち、マクロ定義に対する参照（呼び出し）を含んでいるか否かを判定する（Ｓ１０８）。マクロ呼び出しに該当しない場合は、バッファ内のトークンについてのソースコード２における位置および文字種別の情報に基づいて、トークン内の各文字についての拡張文字を生成して拡張文字配列１１０として出力する（Ｓ１０９）。出力する際には、すでに出力されている拡張文字配列１１０の後端に連結する形で出力する。なお、拡張文字を生成する際の位置情報１１２および文字種別の設定方法については後述する。その後、バッファをクリアした後、次のトークンの処理に移る（Ｓ１１４、Ｓ１０３）。
【００３８】
ステップＳ１０８においてバッファ内のトークンがマクロ呼び出しに該当する部分である場合には、次に、バッファ内のトークンの全部または一部がマクロ呼び出しとして完結し、マクロ定義による展開が可能であるか否かを判定する（Ｓ１１０）。マクロ呼び出しとして完結しておらずマクロ展開できない場合は、次のトークンの処理に移る（Ｓ１１４、Ｓ１０３）。
【００３９】
ステップＳ１１０においてバッファ内の全部または一部のトークンがマクロ呼び出しとして完結し、マクロ展開が可能である場合には、完結している部分のトークンをマクロ定義に対応するトークンにより置き換えて展開する（Ｓ１１１）。このとき、マクロ展開後のトークンの位置の情報は、マクロ展開前の元のトークンの位置の情報をそのまま引き継ぐ。
【００４０】
さらに、置き換えたマクロ展開後のトークンの前後にそれぞれ特殊文字からなるマクロ開始トークンおよびマクロ終了トークン（以下ではこれらを単に「マクロトークン」と記載する場合がある）を付加する（Ｓ１１２）。その後、マクロトークンおよびマクロ展開後のトークンを、多段のマクロ呼び出しの展開を考慮して、トークン列の先頭に戻す（Ｓ１１３）。その後、バッファにおけるトークン列に戻した部分をクリアした後、次のトークンの処理に移る（Ｓ１１４、Ｓ１０３）。
【００４１】
上記の処理をステップＳ１０２で生成されたトークン列（ステップＳ１１３において戻されたトークンを含む）が空になるまで繰り返してマクロ展開の処理を終了する。これにより、ソースコード２に対してマクロ定義によって展開された部分の前後に特殊文字を挿入し、さらに各文字について位置情報１１２等を含むデータ構造からなる拡張文字として表した拡張文字配列１１０を得ることができる。
【００４２】
［文字の位置情報］
図３は、プリプロセッサ１０によって出力された拡張文字配列１１０内の文字（拡張文字）における位置情報１１２の設定および識別の例について説明する図である。図中の左上のソースコード２において、３行目のマクロ呼び出し（“ＭＵＬ（ＮＮ，２０）”）は、プリプロセッサ１０によるマクロ展開によって最終的に“１０＊２０”に展開される。
【００４３】
図３では、このときの当該部分の拡張文字配列１１０の状態が示されている。ここで、拡張文字の種別としては、マクロ展開前のソースコード２の文字がそのまま対応する「通常文字」（図３の例では“２”、“０”）、マクロ展開によって生成された「マクロ文字」（図３の例では“１”、“０”や“＊”）、およびマクロ展開された部分の前後に挿入された特殊文字１１１である「マクロ開始文字」／「マクロ終了文字」（図３の例では左向き／右向き三角）の４種類が設定される。「マクロ開始文字」および「マクロ終了文字」の組は、図３の例では“１０”の前後、および“１０＊２０”の前後にそれぞれ交叉せずに、マクロ呼び出しのネストの関係と同様となるような対応関係で挿入されている。
【００４４】
各拡張文字の種別に対して、ソースコード２における位置情報１１２（例えば行、カラム）は以下のように設定される。「通常文字」については、ソースコード２における対応する文字の位置をそのまま位置情報１１２とする。一方、「マクロ文字」については位置情報１１２を有さないものとする。また、「マクロ開始／終了文字」については、それぞれソースコード２における対応するマクロ呼び出しの開始／終了位置を位置情報１１２として保持するが、後述するように、「マクロ開始文字」もしくは「マクロ終了文字」単体では意味のある位置情報１１２とは取り扱わない、すなわち位置情報を有さないものとする。
【００４５】
［文字列の位置情報］
図４は、プリプロセッサ１０によって出力された拡張文字配列１１０内の文字列における位置情報の識別の例について説明する図である。図４の上段の例は、それぞれ、図３の例に示した拡張文字配列１１０について、“１０”、“＊”、“２０”の文字列に分割したものについての位置情報の識別方法を示しており、中段および下段の例は、“１０＊２０”の文字列についての位置情報の識別方法を示している。
【００４６】
文字列の位置情報、すなわち当該文字列に対応するソースコード２における範囲については、拡張文字配列１１０の文字列内の全ての要素に係る拡張文字の位置情報１１２によって特定される範囲の和によって識別する。ここで要素とは、（１）「マクロ開始／終了文字」の組（「マクロ開始／終了文字」の組がネストされている場合は最外部が優先）、および、（２）「通常文字」（（１）の「マクロ開始／終了文字」の組の間に含まれる場合はそちらを優先）を指すものとする。
【００４７】
図４の上段の左の例では、文字列の先頭（左端）にある「マクロ開始文字」には組となる「マクロ終了文字」がなく単体となっているため、上述したように位置情報１１２を有さないものとする。一方、２つ目の「マクロ開始文字」には、文字列の最後尾（右端）に組となる「マクロ終了文字」があり、かつこの組が最外部である。
【００４８】
「マクロ開始／終了文字」は、組となっている場合にはそれぞれの位置情報１１２を有効とする。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報１１２として、「マクロ開始／終了文字」に囲われた文字列（“１０”）に対応するマクロ呼び出し（“ＮＮ”）の開始位置および終了位置を示すことになる。当該文字列には他の要素がないため、結果として当該文字列はソースコード２において“ＮＮ”の部分を示すことになる。
【００４９】
図４の上段の中央の例では、文字列は“＊”のみであり、これは「マクロ文字」であるため位置情報１１２を有さない。すなわち、対応するソースコード２上の位置はないことになる。
【００５０】
図４の上段の右の例では、文字列の左端から始まる“２”、“０”の文字は、それぞれ「通常文字」であり、ソースコード２における対応する文字の位置を位置情報１１２として有している。一方、右端の「マクロ終了文字」は単体となっているため、位置情報１１２を有さないものとする。従って、当該文字列は、“２”、“０”の位置情報１１２によって特定される範囲の和として、ソースコード２において“２０”の部分を示すことになる。
【００５１】
図４の中段の例では、文字列の左端にある「マクロ開始文字」には組となる「マクロ終了文字」があり、かつこの組が最外部である。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報１１２として上記と同様に対応するマクロ呼び出し（“ＮＮ”の開始位置および終了位置を示すことになる。また、次の“＊”についても上記と同様に「マクロ文字」であるため位置情報１１２を有さない。また、以降の“２”、“０”の文字についても上記と同様に、それぞれ「通常文字」であるためソースコード２における対応する文字の位置を位置情報１１２として有している。従って、当該文字列は、「マクロ開始／終了文字」、および“２”、“０”の位置情報１１２によって特定される範囲の和として、ソースコード２において“ＮＮ，２０”の部分を示すことになる。
【００５２】
図４の下段の例では、文字列の左端にある「マクロ開始文字」には、右端に組となる「マクロ終了文字」があり、かつこの組が最外部である。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報１１２として、当該「マクロ開始／終了文字」に囲われた文字列（“１０＊２０”）に対応するマクロ呼び出し（“ＭＵＬ（ＮＮ，２０）”）の開始位置および終了位置を示すことになる。当該文字列には他の要素がないため、結果として当該文字列はソースコード２において“ＭＵＬ（ＮＮ，２０）”の部分を示すことになる。
【００５３】
このように、文字列の各文字（拡張文字）の種別（特に特殊文字１１１である「マクロ開始／終了文字」）に応じて位置情報１１２を判断して、位置情報１１２によって特定される範囲の和を求めることによって、ソースコード２中におけるマクロ呼び出しも含めた正確な位置情報を識別することができる。
【００５４】
ただし例外として、拡張文字配列１１０内の文字列が上記の“（１）「マクロ開始／終了文字」の組”の要素に該当する場合であっても、当該文字列に対応するマクロ呼び出し自体がマクロ展開によって生成されたものである場合は、当該文字列に対応するソースコード２中の位置情報１１２を有さない。
【００５５】
図５は、拡張文字配列１１０内の文字列が、対応するソースコード２中の位置情報１１２を有さない場合の例を示した図である。図中のソースコード２において、３行目の“Ａ（２０）”のマクロ呼び出しは、プリプロセッサ１０によるマクロ展開によって“２０＊ＮＮ”となり、さらにマクロ展開によって“２０＊１０”となる。ここで、このマクロ展開後のソースコード２、すなわち拡張文字配列１１０における“１０”（およびその前後の「マクロ開始／終了文字」）の部分は、上記の“（１）「マクロ開始／終了文字」の組”の要素に該当する。
【００５６】
しかし、“１０”およびその前後の「マクロ開始／終了文字」に対応するソースコード２上での位置情報を識別しようとした場合、“１０”に対応するマクロ呼び出し（“ＮＮ”）は、元のソースコード２上にはなく、マクロ展開によって生成された中間のソースコード２上にある。従って、“１０”の前後の「マクロ開始／終了文字」の位置情報１１２には、対応するソースコード２上の位置が設定されていないためである。
【００５７】
［トークン、ＡＳＴの位置情報］
図６は、プリプロセッサ１０によって出力されたトークン配列１２０、およびＡＳＴ１３０のノードにおける位置情報の識別の例について説明する図である。図６において、最下段のソースコード２（図１に示したものと同様）に対して、プリプロセッサ１０によって生成された拡張文字配列１１０が示されている。また、拡張文字配列１１０に基づいてレキサ２０によって生成されたトークン配列１２０、およびトークン配列１２０内の各トークンと拡張文字配列１１０内の文字との対応の例が示されている。さらに、トークン配列１２０に基づいてパーサ３０によって生成されたＡＳＴ１３０、およびＡＳＴ１３０の各ノードとトークン配列１２０内の各トークンとの対応の例についても示されている。
【００５８】
ここで、トークン配列１２０内の各トークンは、拡張文字配列１１０からレキサ２０による字句解析によって拡張文字の文字列を分割してトークン化したものである。このとき、レキサ２０は、特殊文字１１１の取り扱いとして、「マクロ開始文字」は後続の文字（「通常文字」および「マクロ文字」）と同一のトークンに含まれるようにし、「マクロ終了文字」は先行の文字（「通常文字」および「マクロ文字」）と同一のトークンに含まれるようにする。
【００５９】
従って、トークンは拡張文字配列１１０の文字列と対応しているため、解析部４０は、トークンについてのソースコード２上での位置情報を識別する際に、トークンに対応する文字列について、上述した文字列の位置情報の識別方法に従って識別すればよい。
【００６０】
また、ＡＳＴ１３０では、各ノードは対応するトークンを含んで構成される。従って、解析部４０は、ＡＳＴ１３０のノードについてのソースコード２上での位置情報を識別する際に、ノードが含む各トークンに対応する拡張文字の文字列を連結した文字列について、上述した文字列の位置情報の識別方法に従って識別すればよい。
【００６１】
ここで、例えば図６に示すように、プリプロセッサ１０によるマクロ展開後のソースコード２（拡張文字配列１１０）における“１０＊２０”という文字列は、“１０”、“＊”、“２０”のトークンに分割される。従って、このマクロ展開後のソースコード２（およびこれから得られるトークン配列１２０）について解析を行う場合には、一般的に、“１０”、“＊”、“２０”の各トークンに対応する位置情報を求めることができるに過ぎない。
【００６２】
一方、ＡＳＴ１３０は、トークン配列１２０からパーサ３０による構文解析によって得られたものであり、各ノードはソースコード２の構文要素を表している。従って、例えば、図６に示すＡＳＴ１３０における最上部のノードは、対応するトークンとして“１０”、“＊”、“２０”の各トークンを含んでいるが、これは単なる“１０”、“＊”、“２０”の文字列の連結ではなく、“１０＊２０”という式を表していることになる。
【００６３】
このように、ＡＳＴ１３０を利用することによって、“１０”、“＊”、“２０”という文字列（トークン）の単なる連結ではなく“１０＊２０”という式として評価することができるため、マクロ展開前のソースコード２における対応する位置情報として、対応するマクロ呼び出しである“ＭＵＬ（ＮＮ，２０）”を正しく識別することができる。
【００６４】
以上に説明したように、本実施の形態のソース解析プログラムによれば、プリプロセッサ１０によるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字１１１を挿入し、さらに各文字についてデータ構造として位置情報１１２を保持して拡張文字とし、拡張文字配列１１０を生成する。また、レキサ２０による字句解析の際に、この拡張文字配列１１０の文字列を切り出してトークンとすることで、位置情報１１２をトークンに埋め込む。
【００６５】
これらにより、パーサ３０による構文解析によって得られるＡＳＴ１３０についても、ノードに含まれるトークンを介して、トークンに対応する拡張文字の文字列からマクロ展開前のソースコード２中におけるマクロ呼び出しも含めた正確な位置情報を容易に識別することが可能となる。
【００６６】
以上、本発明者によってなされた発明を実施の形態に基づき具体的に説明したが、本発明は前記実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で種々変更可能であることはいうまでもない。
【産業上の利用可能性】
【００６７】
本発明は、ソースコードに対してマクロ展開を行った後に字句解析、構文解析を行うソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムに利用可能である。
【符号の説明】
【００６８】
１…ソース解析プログラム、２…ソースコード、
１０…プリプロセッサ、２０…レキサ、３０…パーサ、４０…解析部、
１１０…拡張文字配列、１１１…特殊文字、１１２…位置情報、１２０…トークン配列、１３０…ＡＳＴ。
【図１】
0005385102.tif 000002
【図２】
0005385102.tif 000003
【図３】
0005385102.tif 000004
【図４】
0005385102.tif 000005
【図５】
0005385102.tif 000006
【図６】
0005385102.tif 000007
【図７】
0005385102.tif 000008