説明

ソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラム

【課題】ASTのノードとの間でも、ソースコード中のマクロ呼び出しにおける位置との対応を効率よく把握することを可能とするソース解析プログラムを提供する。
【解決手段】ソースコード2に対してマクロ展開を行って拡張文字配列110を出力するプリプロセッサ10と、拡張文字配列110に対して字句解析によってトークン配列120を出力するレキサ20と、トークン配列120に基づいて構文解析を行いAST130を生成するパーサ30とを有するソース解析プログラム1であって、プリプロセッサ10は、展開したマクロ定義の前後に特殊文字111を挿入し、さらに特殊文字111を含む各文字について位置情報112および文字種別の情報を含む拡張文字からなる拡張文字配列110を出力し、レキサ20は、拡張文字配列110を分割した文字列を対応させてトークンとし、パーサ30は、レキサ20によって生成されたトークンを含んでノードを構成する。

【発明の詳細な説明】
【技術分野】
【0001】
本発明は、プログラミング言語などによって記述されたソースコードに対する構文解析の技術に関し、特に、ソースコードに対してマクロ展開を行った後に字句解析、構文解析を行うソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムに適用して有効な技術に関するものである。
【背景技術】
【0002】
プログラミング言語やタグ言語などによって記述されたソース(以下では「ソースコード」と記載する)に対して、コンパイラやコードチェックツールなどといったプログラムにおいて、ソースコードの内容を把握したり、ソースコードが文法や規則通りに記述されているか否かを判別したりするために構文解析が行われる。
【0003】
このとき、一般的には、まずプリプロセッサによる前処理によって、ソースコードやヘッダファイルなどに定義されているマクロ定義を呼び出している箇所(マクロ呼び出し)が展開される。その後、マクロ展開後のソースコードに対してレキサによる字句解析、パーサによる構文解析が行われ、AST(Abstract Syntax Tree:抽象構文木)が生成される。その後、ASTに対して解析等を行い、その結果、文法が誤っているなどの箇所がある場合には、例えば、「ソースコード中のXX行目のYYYでエラーがある」などの指摘がされる。
【0004】
しかし、字句解析や構文解析は、プリプロセッサによってマクロ呼び出しが展開された後のソースコードに対して行われるため、「ソースコードのXX行目のYYY」といった情報もマクロ展開後のソースコードに対するものとなってしまう。従って、例えば、複数行に及ぶマクロ定義がある場合や、「YYY」という命令がマクロ展開によって生成されたものである場合などでは、マクロ展開後のソースコードにおける「XX行目のYYY」という情報からマクロ展開前のソースコードにおける該当箇所を特定することが困難となる場合がある。
【0005】
これに対し、プリプロセッサによる前処理を行った後も展開前のマクロ呼び出しの情報がなくならないようにする技術として、例えば、特開2007−265095号公報(特許文献1)には、前処理指令の実行段階でのマクロ呼び出しの展開において、その展開前にマクロ展開前を示す文字と、マクロの展開後にマクロ展開後を示す文字とを埋め込むソースプログラム検証プログラムが記載されている。
【0006】
また、非特許文献1には、プリプロセッサによる前処理前のC言語で記載されたソースコードに追跡子を埋め込み、これを観測することで、既存のプリプロセッサを利用して、前処理前後におけるマクロ展開のマッピング情報を得る技術が記載されている。
【先行技術文献】
【特許文献】
【0007】
【特許文献1】特開2007−265095号公報
【非特許文献】
【0008】
【非特許文献1】権藤克彦他、「ソフトウェア工学の基礎13 日本ソフトウェア科学会FOSE 2006」、株式会社近代科学社、2006年11月、p9−18(“TBCppA:追跡子を用いたC前処理系解析器”)
【発明の概要】
【発明が解決しようとする課題】
【0009】
従来技術では、プリプロセッサによる前処理を行う前のソースコードと、前処理を行ってマクロを展開した後のソースコードとの間でマクロ情報を維持してマッピングすることが可能である。すなわち、マクロ展開後のソースコードからマッピング情報に基づいてマクロ展開前のソースコードの内容(マクロ呼び出し)を復元することが可能である。
【0010】
しかしながら従来技術では、プリプロセッサによってマクロ展開した後のソースコードに対して、さらに字句解析・構文解析を行ってASTを生成し、ASTに対して解析等を行う場合に、解析等によって検出したエラー等の箇所について、マクロ展開前のソースコード中のマクロ呼び出しにおける正確な位置情報を特定することが困難であったり、煩雑であったりする場合がある。
【0011】
例えば、図7に示すようなマクロ定義とマクロ呼び出しを含むC言語で記載されたソースコードがある場合に、3行目の命令は、プリプロセッサによるマクロ展開によって“NN”のマクロ呼び出しが“10”に展開され、さらに、“MUL(10,20)”のマクロ呼び出しが“10*20”に展開される。このとき、マクロ展開後のソースコードの命令文“a=10*20;”において、同じ“10”を左端とするトークンでも、“10”を対象とする場合と、“10*20”を対象とする場合とでは、マクロ展開前のソースコードにおける対応するマクロ呼び出しが異なる(“NN”および“MUL(NN,20)”)。従って、図中の下線部に示すように、マクロ展開前のソースコードにおける位置情報についてもこれを考慮して対応するマクロ呼び出しの部分を正しく示す必要がある。
【0012】
しかしながら、従来技術では、ASTの木構造とマクロ展開前のソースコードとの間でのマクロ情報の維持については考慮されておらずマッピング情報を有さないため、エラー等を有するASTのノード(図7の例における“10”や“10*20”)に対応する、マクロ展開前のソースコード中のマクロ呼び出しにおける正確な位置情報(範囲)を容易に特定することは困難である。特に、“10*20”のような、複数のトークンの結合からなるノードについては、単に各トークン(“10”、“*”、“20”)についての対応する位置をそれぞれ把握するだけでは、マクロ呼び出しにおける正確な位置情報(“MUL(NN,20)”の全体)を特定することは困難である。
【0013】
また、例えば、非特許文献1に記載されたような技術では、複雑な多段展開のマクロについて正しくマッピング情報を得ることができなかったり、追跡子を埋め込むことによってソースコードのサイズの増大が非常に大きくなったりなど、効率的に利用するには制限がある場合もある。
【0014】
そこで本発明の目的は、プリプロセッサによるマクロ展開後のソースコードに対する字句解析・構文解析によって得られるASTのノードに対しても、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を効率よく識別することを可能とするソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムを提供することにある。
【0015】
本発明の前記ならびにその他の目的と新規な特徴は、本明細書の記述および添付図面から明らかになるであろう。
【課題を解決するための手段】
【0016】
本願において開示される発明のうち、代表的なものの概要を簡単に説明すれば、以下のとおりである。
【0017】
本発明の代表的な実施の形態によるソース解析プログラムは、マクロ定義およびマクロ呼び出しを含む第1のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行って第2のソースコードを出力するプリプロセッサと、前記プリプロセッサによって出力された前記第2のソースコードに対して、字句解析によってトークンに分割してトークン配列を出力するレキサと、前記レキサによって出力された前記トークン配列に基づいて構文解析を行い、抽象構文木を生成するパーサとを有するソース解析プログラムであって、以下の特徴を有するものである。
【0018】
すなわち、前記プリプロセッサは、前記第1のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第1のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第2のソースコードとして出力し、前記レキサは、前記トークン配列を出力する際に、前記プリプロセッサによって出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、前記パーサは、前記抽象構文木を生成する際に、前記レキサによって生成された前記トークンを含んでノードを構成することを特徴とする。
【発明の効果】
【0019】
本願において開示される発明のうち、代表的なものによって得られる効果を簡単に説明すれば以下のとおりである。
【0020】
本発明の代表的な実施の形態によれば、プリプロセッサによるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字を挿入し、さらに各文字についてデータ構造として位置情報を保持する。この位置情報を字句解析によって得られるトークンに埋め込むことにより、構文解析によって得られるASTについても、ノードに含まれるトークンを介して、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を効率よく識別することが可能となる。
【図面の簡単な説明】
【0021】
【図1】本発明の一実施の形態であるソース解析プログラムの構成例の概要について示した図である。
【図2】本発明の一実施の形態におけるプリプロセッサでのマクロ展開の処理の例について概要を示したフローチャートである。
【図3】本発明の一実施の形態におけるプリプロセッサによって出力された拡張文字配列内の文字における位置情報の設定および識別の例について説明する図である。
【図4】本発明の一実施の形態におけるプリプロセッサによって出力された拡張文字配列内の文字列における位置情報の識別の例について説明する図である。
【図5】本発明の一実施の形態における拡張文字配列内の文字列が、対応するソースコード中の位置情報を有さない場合の例を示した図である。
【図6】本発明の一実施の形態におけるプリプロセッサによって出力されたトークン配列、およびASTのノードにおける位置情報の識別の例について説明する図である。
【図7】トークンに応じてマクロ展開前のソースコード中のマクロ呼び出しにおける位置情報を特定する場合の例を示した図である。
【発明を実施するための形態】
【0022】
以下、本発明の実施の形態を図面に基づいて詳細に説明する。なお、実施の形態を説明するための全図において、同一部には原則として同一の符号を付し、その繰り返しの説明は省略する。
【0023】
本発明の一実施の形態であるソース解析プログラムは、マクロ定義およびマクロ呼び出しを含むソースコードに対して、プリプロセッサによるマクロ展開を行った後に字句解析、構文解析を行ってASTを生成し、ASTに対して解析(例えば、文書構造についての意味的な解析や、所定の文法や記述ルール、規約などに沿っているか否かのチェックなど)を行うことでソースコードの記述内容についての解析などを行うソフトウェアプログラムである。
【0024】
本実施の形態のソース解析プログラムは、プリプロセッサによるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字を挿入し、さらに各文字についてデータ構造として位置情報を保持する。さらに、この位置情報を字句解析によって得られるトークンに埋め込むことにより、構文解析によって得られるASTについても、ノードに含まれるトークンを介して、マクロ展開前のソースコード中におけるマクロ呼び出しも含めた正確な位置情報を容易に識別することを可能とするものである。
【0025】
[プログラム構成]
図1は、本発明の一実施の形態であるソース解析プログラムの構成例の概要について示した図である。ソース解析プログラム1は、例えば、プリプロセッサ10、レキサ20、パーサ30、および解析部40の各プログラムを有し、ソースコード2を入力としてその記述内容についての解析を行うソフトウェアプログラムである。
【0026】
このソース解析プログラム1は、例えば、コンパイラやコードチェックツール、文書解析プログラムなど、ソースコード2の文書構造を解析する処理を含む種々のプログラムの一部、または全部として実装される。従って、入力となるソースコードについても、C言語などのプログラミング言語やXML(eXtensible Markup Language)などのタグ言語によって記述されたものに限らず、マクロ定義およびマクロ呼び出しを有するものであれば適用可能である。また、ソースコード2は複数のファイルから構成されていてもよく、例えば、マクロ定義を有するヘッダファイルなどを含んでいてもよい。
【0027】
プリプロセッサ10は、ソースコード2に対して、マクロ呼び出しをマクロ定義によって展開するマクロ展開を含む前処理を行って、前処理後のソースコード2を出力するソフトウェアプログラムである。本実施の形態のプリプロセッサ10は、一般的なプリプロセッサと同様に、ソースコード2の文字を読み込んで、マクロ展開を行った後に文字配列としてソースコード2を出力するが、さらに、マクロ呼び出しをマクロ定義によって展開する際に、展開したマクロ定義の前後に特殊文字111を挿入する。これにより、マクロ展開によって生成された範囲が識別可能となるようにする。
【0028】
また、文字配列を出力する際に、各文字を、単なる文字データではなくソースコード2上での位置情報112(例えば行、カラム)と、文字種別(通常文字、マクロ展開によって生成されたマクロ文字、および特殊文字の区分)の情報を含むデータ構造からなる拡張文字とし、拡張文字からなる拡張文字配列110として出力する。拡張文字のデータ構造は上記のものに限定されず、例えば、さらにマクロ展開後のソースコード2上での位置情報などを有していてもよい。また、拡張文字の実装方法についても特に限定されず、C言語における構造体や、オブジェクト指向言語におけるクラス、タプルなど種々の方法で実装することができる。プリプロセッサ10での処理および拡張文字配列110の詳細については後述する。
【0029】
レキサ20は、プリプロセッサ10によってマクロ展開を含む前処理が行われたソースコード2(すなわち拡張文字配列110)を入力として、字句解析を行うソフトウェアプログラムである。本実施の形態のレキサ20は、マクロ展開後のソースコード2(拡張文字配列110)を字句解析によってトークンに分割(トークン化)し、トークン配列120を出力する。このとき、拡張文字配列110におけるトークンに対応する拡張文字の情報(特に位置情報112)がトークンに埋め込まれる。なお、字句解析の技術等については一般的なレキサ(もしくはトークナイザ、字句解析器など)におけるものと同様であるため説明は省略する。
【0030】
パーサ30は、レキサ20によって出力されたトークン配列120に基づいて構文解析を行い、AST130を生成するソフトウェアプログラムである。なお、構文解析の技術やAST130の構造等については、一般的なパーサ(もしくは構文解析器など)におけるものと同様であるため説明は省略する。
【0031】
解析部40は、パーサ30によって出力されたAST130を参照して解析等を行うことにより、ソースコード2の記述内容についての解析を行うソフトウェアプログラムである。このとき、AST130の各ノードに対応するトークン配列120中のトークンに対応する拡張文字の文字列(特に特殊文字111)、および拡張文字の位置情報112を参照することで、AST130の各ノードに対応するマクロ呼び出しを含むソースコード2での正確な位置情報を識別することができる。位置情報の識別方法の詳細については後述する。
【0032】
解析部40としては、例えば、コンパイラにおいてAST130に対して意味解析を行ってオブジェクトコードを生成するコード生成部や、コードチェックツールにおいてコード作成規約・ルール等とのマッチングなどによりソースコードの記述内容をチェックするチェックロジックなどが該当する。なお、AST130の各ノードに対応するソースコード2での位置情報の識別に係る部分以外の解析等の技術(例えば、意味解析や最適化、ルールや規約とのマッチング等)については、コンパイラやコードチェックツール等における一般的なものと同様であるため説明は省略する。
【0033】
[プリプロセッサでの処理フロー]
図2は、プリプロセッサ10でのマクロ展開の処理の例について概要を示したフローチャートである。ソースコード2を入力して処理を開始すると、まず、ソースコード2の各文字を切り出して文字配列を生成する(S101)。次に、ソースコード2の文字配列に対して字句解析を行ってトークンを切り出し、トークン列を生成する(S102)。ここでは、一般的に正規表現などレキサ20による字句解析と同等の技術を用いて文字配列をトークンに分割する。このとき、各トークンにはソースコード2における位置(例えば、開始・終了位置)および文字種別の情報を別途保持する。
【0034】
その後、トークン列内の各トークンを対象として処理を繰り返すループ処理を開始する(S103)。ループ処理では、トークン列の先頭から処理対象のトークンをマクロ展開用のバッファに読み込む(S104)。このとき、バッファ内にトークンが存在する場合は後端に連結する形で読み込む。なお、当該バッファは、プリプロセッサ10がマクロ展開処理時にプリプロセッサ10が動作するコンピュータシステムのメモリ上に設けるデータ領域である。
【0035】
次に、バッファ内のトークンがマクロ定義に該当する部分であるか否かを判定する(S105)。マクロ定義に該当する部分である場合は、バッファ内のトークンがマクロ定義として完結しているか否かを判定する(S106)。マクロ定義として完結している場合には、バッファ内のトークンの内容(マクロ定義)をマクロテーブルに出力し(S107)、バッファをクリアする。なお、マクロテーブルに出力したトークンの内容(マクロ定義)について、後の解析において利用するために、後述するステップS109の処理と同様に拡張文字として出力してもよい。
【0036】
ステップS106においてバッファ内のトークンがマクロ定義として完結していない場合は、次のトークンの処理に移る(S114、S103)。なお、ソースコード2においてマクロ定義はマクロ呼び出しよりも前に記述されている必要があるため、通常は、以降のマクロ展開の処理が実行される前に、上記の処理によってマクロテーブルにマクロ定義が保持されることになる。
【0037】
ステップS105においてバッファ内のトークンがマクロ定義に該当しない場合は、次に、バッファ内のトークンがマクロ呼び出しに該当する部分であるか否か、すなわち、マクロ定義に対する参照(呼び出し)を含んでいるか否かを判定する(S108)。マクロ呼び出しに該当しない場合は、バッファ内のトークンについてのソースコード2における位置および文字種別の情報に基づいて、トークン内の各文字についての拡張文字を生成して拡張文字配列110として出力する(S109)。出力する際には、すでに出力されている拡張文字配列110の後端に連結する形で出力する。なお、拡張文字を生成する際の位置情報112および文字種別の設定方法については後述する。その後、バッファをクリアした後、次のトークンの処理に移る(S114、S103)。
【0038】
ステップS108においてバッファ内のトークンがマクロ呼び出しに該当する部分である場合には、次に、バッファ内のトークンの全部または一部がマクロ呼び出しとして完結し、マクロ定義による展開が可能であるか否かを判定する(S110)。マクロ呼び出しとして完結しておらずマクロ展開できない場合は、次のトークンの処理に移る(S114、S103)。
【0039】
ステップS110においてバッファ内の全部または一部のトークンがマクロ呼び出しとして完結し、マクロ展開が可能である場合には、完結している部分のトークンをマクロ定義に対応するトークンにより置き換えて展開する(S111)。このとき、マクロ展開後のトークンの位置の情報は、マクロ展開前の元のトークンの位置の情報をそのまま引き継ぐ。
【0040】
さらに、置き換えたマクロ展開後のトークンの前後にそれぞれ特殊文字からなるマクロ開始トークンおよびマクロ終了トークン(以下ではこれらを単に「マクロトークン」と記載する場合がある)を付加する(S112)。その後、マクロトークンおよびマクロ展開後のトークンを、多段のマクロ呼び出しの展開を考慮して、トークン列の先頭に戻す(S113)。その後、バッファにおけるトークン列に戻した部分をクリアした後、次のトークンの処理に移る(S114、S103)。
【0041】
上記の処理をステップS102で生成されたトークン列(ステップS113において戻されたトークンを含む)が空になるまで繰り返してマクロ展開の処理を終了する。これにより、ソースコード2に対してマクロ定義によって展開された部分の前後に特殊文字を挿入し、さらに各文字について位置情報112等を含むデータ構造からなる拡張文字として表した拡張文字配列110を得ることができる。
【0042】
[文字の位置情報]
図3は、プリプロセッサ10によって出力された拡張文字配列110内の文字(拡張文字)における位置情報112の設定および識別の例について説明する図である。図中の左上のソースコード2において、3行目のマクロ呼び出し(“MUL(NN,20)”)は、プリプロセッサ10によるマクロ展開によって最終的に“10*20”に展開される。
【0043】
図3では、このときの当該部分の拡張文字配列110の状態が示されている。ここで、拡張文字の種別としては、マクロ展開前のソースコード2の文字がそのまま対応する「通常文字」(図3の例では“2”、“0”)、マクロ展開によって生成された「マクロ文字」(図3の例では“1”、“0”や“*”)、およびマクロ展開された部分の前後に挿入された特殊文字111である「マクロ開始文字」/「マクロ終了文字」(図3の例では左向き/右向き三角)の4種類が設定される。「マクロ開始文字」および「マクロ終了文字」の組は、図3の例では“10”の前後、および“10*20”の前後にそれぞれ交叉せずに、マクロ呼び出しのネストの関係と同様となるような対応関係で挿入されている。
【0044】
各拡張文字の種別に対して、ソースコード2における位置情報112(例えば行、カラム)は以下のように設定される。「通常文字」については、ソースコード2における対応する文字の位置をそのまま位置情報112とする。一方、「マクロ文字」については位置情報112を有さないものとする。また、「マクロ開始/終了文字」については、それぞれソースコード2における対応するマクロ呼び出しの開始/終了位置を位置情報112として保持するが、後述するように、「マクロ開始文字」もしくは「マクロ終了文字」単体では意味のある位置情報112とは取り扱わない、すなわち位置情報を有さないものとする。
【0045】
[文字列の位置情報]
図4は、プリプロセッサ10によって出力された拡張文字配列110内の文字列における位置情報の識別の例について説明する図である。図4の上段の例は、それぞれ、図3の例に示した拡張文字配列110について、“10”、“*”、“20”の文字列に分割したものについての位置情報の識別方法を示しており、中段および下段の例は、“10*20”の文字列についての位置情報の識別方法を示している。
【0046】
文字列の位置情報、すなわち当該文字列に対応するソースコード2における範囲については、拡張文字配列110の文字列内の全ての要素に係る拡張文字の位置情報112によって特定される範囲の和によって識別する。ここで要素とは、(1)「マクロ開始/終了文字」の組(「マクロ開始/終了文字」の組がネストされている場合は最外部が優先)、および、(2)「通常文字」((1)の「マクロ開始/終了文字」の組の間に含まれる場合はそちらを優先)を指すものとする。
【0047】
図4の上段の左の例では、文字列の先頭(左端)にある「マクロ開始文字」には組となる「マクロ終了文字」がなく単体となっているため、上述したように位置情報112を有さないものとする。一方、2つ目の「マクロ開始文字」には、文字列の最後尾(右端)に組となる「マクロ終了文字」があり、かつこの組が最外部である。
【0048】
「マクロ開始/終了文字」は、組となっている場合にはそれぞれの位置情報112を有効とする。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報112として、「マクロ開始/終了文字」に囲われた文字列(“10”)に対応するマクロ呼び出し(“NN”)の開始位置および終了位置を示すことになる。当該文字列には他の要素がないため、結果として当該文字列はソースコード2において“NN”の部分を示すことになる。
【0049】
図4の上段の中央の例では、文字列は“*”のみであり、これは「マクロ文字」であるため位置情報112を有さない。すなわち、対応するソースコード2上の位置はないことになる。
【0050】
図4の上段の右の例では、文字列の左端から始まる“2”、“0”の文字は、それぞれ「通常文字」であり、ソースコード2における対応する文字の位置を位置情報112として有している。一方、右端の「マクロ終了文字」は単体となっているため、位置情報112を有さないものとする。従って、当該文字列は、“2”、“0”の位置情報112によって特定される範囲の和として、ソースコード2において“20”の部分を示すことになる。
【0051】
図4の中段の例では、文字列の左端にある「マクロ開始文字」には組となる「マクロ終了文字」があり、かつこの組が最外部である。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報112として上記と同様に対応するマクロ呼び出し(“NN”の開始位置および終了位置を示すことになる。また、次の“*”についても上記と同様に「マクロ文字」であるため位置情報112を有さない。また、以降の“2”、“0”の文字についても上記と同様に、それぞれ「通常文字」であるためソースコード2における対応する文字の位置を位置情報112として有している。従って、当該文字列は、「マクロ開始/終了文字」、および“2”、“0”の位置情報112によって特定される範囲の和として、ソースコード2において“NN,20”の部分を示すことになる。
【0052】
図4の下段の例では、文字列の左端にある「マクロ開始文字」には、右端に組となる「マクロ終了文字」があり、かつこの組が最外部である。従って、当該「マクロ開始文字」および「マクロ終了文字」は、それぞれ位置情報112として、当該「マクロ開始/終了文字」に囲われた文字列(“10*20”)に対応するマクロ呼び出し(“MUL(NN,20)”)の開始位置および終了位置を示すことになる。当該文字列には他の要素がないため、結果として当該文字列はソースコード2において“MUL(NN,20)”の部分を示すことになる。
【0053】
このように、文字列の各文字(拡張文字)の種別(特に特殊文字111である「マクロ開始/終了文字」)に応じて位置情報112を判断して、位置情報112によって特定される範囲の和を求めることによって、ソースコード2中におけるマクロ呼び出しも含めた正確な位置情報を識別することができる。
【0054】
ただし例外として、拡張文字配列110内の文字列が上記の“(1)「マクロ開始/終了文字」の組”の要素に該当する場合であっても、当該文字列に対応するマクロ呼び出し自体がマクロ展開によって生成されたものである場合は、当該文字列に対応するソースコード2中の位置情報112を有さない。
【0055】
図5は、拡張文字配列110内の文字列が、対応するソースコード2中の位置情報112を有さない場合の例を示した図である。図中のソースコード2において、3行目の“A(20)”のマクロ呼び出しは、プリプロセッサ10によるマクロ展開によって“20*NN”となり、さらにマクロ展開によって“20*10”となる。ここで、このマクロ展開後のソースコード2、すなわち拡張文字配列110における“10”(およびその前後の「マクロ開始/終了文字」)の部分は、上記の“(1)「マクロ開始/終了文字」の組”の要素に該当する。
【0056】
しかし、“10”およびその前後の「マクロ開始/終了文字」に対応するソースコード2上での位置情報を識別しようとした場合、“10”に対応するマクロ呼び出し(“NN”)は、元のソースコード2上にはなく、マクロ展開によって生成された中間のソースコード2上にある。従って、“10”の前後の「マクロ開始/終了文字」の位置情報112には、対応するソースコード2上の位置が設定されていないためである。
【0057】
[トークン、ASTの位置情報]
図6は、プリプロセッサ10によって出力されたトークン配列120、およびAST130のノードにおける位置情報の識別の例について説明する図である。図6において、最下段のソースコード2(図1に示したものと同様)に対して、プリプロセッサ10によって生成された拡張文字配列110が示されている。また、拡張文字配列110に基づいてレキサ20によって生成されたトークン配列120、およびトークン配列120内の各トークンと拡張文字配列110内の文字との対応の例が示されている。さらに、トークン配列120に基づいてパーサ30によって生成されたAST130、およびAST130の各ノードとトークン配列120内の各トークンとの対応の例についても示されている。
【0058】
ここで、トークン配列120内の各トークンは、拡張文字配列110からレキサ20による字句解析によって拡張文字の文字列を分割してトークン化したものである。このとき、レキサ20は、特殊文字111の取り扱いとして、「マクロ開始文字」は後続の文字(「通常文字」および「マクロ文字」)と同一のトークンに含まれるようにし、「マクロ終了文字」は先行の文字(「通常文字」および「マクロ文字」)と同一のトークンに含まれるようにする。
【0059】
従って、トークンは拡張文字配列110の文字列と対応しているため、解析部40は、トークンについてのソースコード2上での位置情報を識別する際に、トークンに対応する文字列について、上述した文字列の位置情報の識別方法に従って識別すればよい。
【0060】
また、AST130では、各ノードは対応するトークンを含んで構成される。従って、解析部40は、AST130のノードについてのソースコード2上での位置情報を識別する際に、ノードが含む各トークンに対応する拡張文字の文字列を連結した文字列について、上述した文字列の位置情報の識別方法に従って識別すればよい。
【0061】
ここで、例えば図6に示すように、プリプロセッサ10によるマクロ展開後のソースコード2(拡張文字配列110)における“10*20”という文字列は、“10”、“*”、“20”のトークンに分割される。従って、このマクロ展開後のソースコード2(およびこれから得られるトークン配列120)について解析を行う場合には、一般的に、“10”、“*”、“20”の各トークンに対応する位置情報を求めることができるに過ぎない。
【0062】
一方、AST130は、トークン配列120からパーサ30による構文解析によって得られたものであり、各ノードはソースコード2の構文要素を表している。従って、例えば、図6に示すAST130における最上部のノードは、対応するトークンとして“10”、“*”、“20”の各トークンを含んでいるが、これは単なる“10”、“*”、“20”の文字列の連結ではなく、“10*20”という式を表していることになる。
【0063】
このように、AST130を利用することによって、“10”、“*”、“20”という文字列(トークン)の単なる連結ではなく“10*20”という式として評価することができるため、マクロ展開前のソースコード2における対応する位置情報として、対応するマクロ呼び出しである“MUL(NN,20)”を正しく識別することができる。
【0064】
以上に説明したように、本実施の形態のソース解析プログラムによれば、プリプロセッサ10によるマクロ展開の際に、マクロ展開された文字列の前後に特殊文字111を挿入し、さらに各文字についてデータ構造として位置情報112を保持して拡張文字とし、拡張文字配列110を生成する。また、レキサ20による字句解析の際に、この拡張文字配列110の文字列を切り出してトークンとすることで、位置情報112をトークンに埋め込む。
【0065】
これらにより、パーサ30による構文解析によって得られるAST130についても、ノードに含まれるトークンを介して、トークンに対応する拡張文字の文字列からマクロ展開前のソースコード2中におけるマクロ呼び出しも含めた正確な位置情報を容易に識別することが可能となる。
【0066】
以上、本発明者によってなされた発明を実施の形態に基づき具体的に説明したが、本発明は前記実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で種々変更可能であることはいうまでもない。
【産業上の利用可能性】
【0067】
本発明は、ソースコードに対してマクロ展開を行った後に字句解析、構文解析を行うソース解析プログラム、プリプロセッサ、レキサ、および構文木解析プログラムに利用可能である。
【符号の説明】
【0068】
1…ソース解析プログラム、2…ソースコード、
10…プリプロセッサ、20…レキサ、30…パーサ、40…解析部、
110…拡張文字配列、111…特殊文字、112…位置情報、120…トークン配列、130…AST。

【特許請求の範囲】
【請求項1】
マクロ定義およびマクロ呼び出しを含む第1のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行って第2のソースコードを出力するプリプロセッサと、
前記プリプロセッサによって出力された前記第2のソースコードに対して、字句解析によってトークンに分割してトークン配列を出力するレキサと、
前記レキサによって出力された前記トークン配列に基づいて構文解析を行い、抽象構文木を生成するパーサとを有するソース解析プログラムであって、
前記プリプロセッサは、前記第1のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第1のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第2のソースコードとして出力し、
前記レキサは、前記トークン配列を出力する際に、前記プリプロセッサによって出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、
前記パーサは、前記抽象構文木を生成する際に、前記レキサによって生成された前記トークンを含んでノードを構成することを特徴とするソース解析プログラム。
【請求項2】
請求項1に記載のソース解析プログラムにおいて、
前記プリプロセッサは、前記拡張文字に係る前記文字種別として、前記第1のソースコードにおける文字がそのまま対応する通常文字と、マクロ展開によって展開された前記マクロ定義に係る文字であるマクロ文字と、マクロ展開によって展開された前記マクロ定義の前および後に挿入される前記特殊文字であるマクロ開始文字およびマクロ終了文字を有し、
前記通常文字に係る前記位置情報としては、前記第1のソースコードにおける対応する文字の位置を設定し、前記マクロ文字に係る前記位置情報については設定せず、前記マクロ開始文字および前記マクロ終了文字に係る前記位置情報としては、それぞれ前記第1のソースコードにおける対応する前記マクロ定義に係る前記マクロ呼び出しの開始位置および終了位置を設定することを特徴とするソース解析プログラム。
【請求項3】
請求項2に記載のソース解析プログラムにおいて、
前記レキサは、前記第2のソースコードに対して、字句解析によって前記トークンに分割する際に、前記マクロ開始文字については、後続の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにし、前記マクロ終了文字については、先行の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにすることを特徴とするソース解析プログラム。
【請求項4】
請求項1〜3のいずれか1項に記載のソース解析プログラムにおいて、
さらに、前記パーサによって出力された前記抽象構文木を参照して解析等を行うことにより、前記第1のソースコードの記述内容についての解析を行う解析部を有し、
前記解析部は、前記抽象構文木の各ノードに含まれる前記トークンに対応する前記拡張文字の文字列に基づいて、前記各ノードに対応する前記第1のソースコードにおける位置の情報を識別することを特徴とするソース解析プログラム。
【請求項5】
請求項4に記載のソース解析プログラムにおいて、
前記解析部は、前記拡張文字の文字列に対応する前記第1のソースコードにおける位置の情報を、前記拡張文字の文字列に含まれる全ての要素に係る前記拡張文字の前記位置情報によって特定される範囲の和に基づいて識別し、
前記要素は、前記マクロ開始文字と前記マクロ終了文字の最外部の組、もしくは前記組の間に含まれない前記通常文字であることを特徴とするソース解析プログラム。
【請求項6】
マクロ定義およびマクロ呼び出しを含む第1のソースコードに対して、前記マクロ呼び出しを前記マクロ定義によって展開するマクロ展開を含む前処理を行って第2のソースコードを出力するプリプロセッサであって、
前記プリプロセッサは、前記第1のソースコードに対してマクロ展開を行う際に、展開した前記マクロ定義の前後に特殊文字を挿入し、さらに、前記特殊文字を含む各文字について、前記第1のソースコード上での位置情報、および文字種別の情報を含む拡張文字とし、前記拡張文字からなる拡張文字配列を前記第2のソースコードとして出力し、
前記拡張文字に係る前記文字種別として、前記第1のソースコードにおける文字がそのまま対応する通常文字と、マクロ展開によって展開された前記マクロ定義に係る文字であるマクロ文字と、マクロ展開によって展開された前記マクロ定義の前および後に挿入される前記特殊文字であるマクロ開始文字およびマクロ終了文字を有し、
前記通常文字に係る前記位置情報としては、前記第1のソースコードにおける対応する文字の位置を設定し、前記マクロ文字に係る前記位置情報については設定せず、前記マクロ開始文字および前記マクロ終了文字に係る前記位置情報としては、それぞれ前記第1のソースコードにおける対応する前記マクロ定義に係る前記マクロ呼び出しの開始位置および終了位置を設定することを特徴とするプリプロセッサ。
【請求項7】
請求項6に記載のプリプロセッサによって出力された前記第2のソースコードに対して、字句解析によってトークンに分割してトークン配列を出力するレキサであって、
前記レキサは、前記トークン配列を出力する際に、前記プリプロセッサによって出力された前記拡張文字配列を分割した文字列を対応させて前記トークンとし、
前記マクロ開始文字については、後続の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにし、前記マクロ終了文字については、先行の前記通常文字もしくは前記マクロ文字と同一の前記トークンに含まれるようにすることを特徴とするレキサ。
【請求項8】
請求項1〜3のいずれか1項に記載のソース解析プログラムによって出力された前記抽象構文木を参照して解析等を行うことにより、前記第1のソースコードの記述内容についての解析を行う構文木解析プログラムであって、
前記抽象構文木の各ノードに含まれる前記トークンに対応する前記拡張文字の文字列に基づいて、前記各ノードに対応する前記第1のソースコードにおける位置の情報を識別することを特徴とする構文木解析プログラム。
【請求項9】
請求項8に記載の構文木解析プログラムにおいて、
前記拡張文字の文字列に対応する前記ソースコードにおける位置の情報を、前記拡張文字の文字列に含まれる全ての要素に係る前記拡張文字の前記位置情報によって特定される範囲の和に基づいて識別し、
前記要素は、前記マクロ開始文字と前記マクロ終了文字の最外部の組、もしくは前記組の間に含まれない前記通常文字であることを特徴とする構文木解析プログラム。

【図1】
image rotate

【図2】
image rotate

【図3】
image rotate

【図4】
image rotate

【図5】
image rotate

【図6】
image rotate

【図7】
image rotate


【公開番号】特開2011−113147(P2011−113147A)
【公開日】平成23年6月9日(2011.6.9)
【国際特許分類】
【出願番号】特願2009−266739(P2009−266739)
【出願日】平成21年11月24日(2009.11.24)
【出願人】(000155469)株式会社野村総合研究所 (1,067)
【Fターム(参考)】