(57)【特許請求の範囲】
【請求項１】
関数型言語で記述された制御処理プログラムを手続型の命令処理を行なう装置で実行可能な言語形式に変換する言語変換装置において、
関数型言語の命令／変数オペランドの各要素の配列を記憶した関数型言語記憶部と、
前記配列の各要素を取得し、その各要素のうちで前記命令に対応する関数および前記変数オペランドをノードとしたツリー構造を作成し、該ツリー構造を記憶するツリー構造記憶部に出力するツリー構造作成部と、
前記ツリー構造中の子供ノードを持たないノードであるリーフ以外のノードにインスタンス名を付与するインスタンス名付与部と、
前記インスタンス名を付与されたツリー構造に対して、子供ノードがリーフしかないノードを見つけ、そのノードに記述された関数を呼び出し、その呼び出した結果の代入文を、代入先をそのノードに付与されたインスタンス名として作成し、手続型言語の命令群を記憶する手続型言語記憶部に出力する代入文作成部と、
前記手続型言語記憶部に出力したノードの子供ノードのすべてを前記ツリー構造中から削除する削除処理部と、を有し、
前記ツリー構造が１つのノードになるまで、前記代入文作成部による処理および前記削除処理部による処理を繰り返すことを特徴とする言語変換装置。
【請求項２】
前記ノードは、ノード名称、呼び出し元の関数がその引数をポイントするときに使用する子供ノードへのポインタ、呼び出し元の関数が同一である引数間において次の引数をポイントするときに使用する次ノードへのポインタの各項目を有し、
前記ツリー構造作成部は、前記関数型言語記憶部の配列から、関数を読み出したときに、その関数の名称をノード名称に持つノードを新規作成し、その新規作成したノードを現在処理中ノードとし、
前記関数型言語記憶部の配列から、オペランドを読み出したときに、そのオペランドの名称をノード名称に持つノードを新規作成し、その新規作成したノードを現在処理中ノードとし、その新規作成したノードの子供ノードへのポインタを無効とし、
前記関数型言語記憶部の配列から、関数終了子を読み出したときに、そのときの現在処理中ノードの次ノードへのポインタを無効とし、その終了した関数のノードを現在処理中ノードとすることを、前記関数型言語記憶部の配列から要素を読み出す度に実行する、ことを特徴とする請求項１記載の言語変換装置。
【請求項３】
前記ツリー構造作成部は、
現在処理中ノードが関数に対応したものであり、かつ、前記新規作成したノードが関数に対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードがオペランドに対応したものであり、かつ、前記新規作成したノードがオペランドに対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードがオペランドに対応したものであり、かつ、前記新規作成したノードが関数に対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードが関数に対応したものであり、かつ、前記新規作成したノードがオペランドに対応したもののときに、前記新規作成したノードの子供ノードへのポインタを無効とする、ことを特徴とする請求項２記載の言語変換装置。
【請求項４】
関数型言語で記述された制御処理プログラムを手続型の命令処理を行なう装置で実行可能な言語形式に変換する処理を、関数型言語の命令／変数オペランドの各要素の配列を記憶した関数型言語記憶部と、手続型言語の命令群を記憶する手続型言語記憶部とを有する言語変換装置に実行させるプログラムにおいて、
前記関数型言語記憶部の配列の各要素を取得し、その各要素のうちで前記命令に対応する関数および前記変数オペランドをノードとしたツリー構造を作成し、該ツリー構造を記憶するツリー構造記憶部に出力するツリー構造作成ステップと、
前記ツリー構造中の子供ノードを持たないノードであるリーフ以外のノードにインスタンス名を付与するインスタンス名付与ステップと、
前記インスタンス名を付与されたツリー構造に対して、子供ノードがリーフしかないノードを見つけ、そのノードに記述された関数を呼び出し、その呼び出した結果の代入文を、代入先をそのノードに付与されたインスタンス名として作成し、前記手続型言語記憶部に出力する代入文作成ステップと、
前記手続型言語記憶部に出力したノードの子供ノードのすべてを前記ツリー構造中から削除する削除処理ステップと、を有し、
前記ツリー構造が１つのノードになるまで、前記代入文作成ステップおよび前記削除処理ステップを繰り返すことを特徴とする言語変換プログラム。
【請求項５】
前記ノードは、ノード名称、呼び出し元の関数がその引数をポイントするときに使用する子供ノードへのポインタ、呼び出し元の関数が同一である引数間において次の引数をポイントするときに使用する次ノードへのポインタの各項目を有し、
前記ツリー構造作成ステップにおいて、前記関数型言語記憶部の配列から、関数を読み出したときに、その関数の名称をノード名称に持つノードを新規作成し、その新規作成したノードを現在処理中ノードとし、
前記関数型言語記憶部の配列から、オペランドを読み出したときに、そのオペランドの名称をノード名称に持つノードを新規作成し、その新規作成したノードを現在処理中ノードとし、その新規作成したノードの子供ノードへのポインタを無効とし、
前記関数型言語記憶部の配列から、関数終了子を読み出したときに、そのときの現在処理中ノードの次ノードへのポインタを無効とし、その終了した関数のノードを現在処理中ノードとすることを、前記関数型言語記憶部の配列から要素を読み出す度に実行する、ことを特徴とする請求項４記載の言語変換プログラム。
【請求項６】
さらに、前記ツリー構造作成ステップにおいて、
現在処理中ノードが関数に対応したものであり、かつ、前記新規作成したノードが関数に対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードがオペランドに対応したものであり、かつ、前記新規作成したノードがオペランドに対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードがオペランドに対応したものであり、かつ、前記新規作成したノードが関数に対応したもののときに、前記新規作成したノードの次ノードへのポインタを無効とし、
現在処理中ノードが関数に対応したものであり、かつ、前記新規作成したノードがオペランドに対応したもののときに、前記新規作成したノードの子供ノードへのポインタを無効とする、ことを特徴とする請求項５記載の言語変換プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、関数型言語で記述されたプログラムを関数型言語処理に不向きな演算処理装置において実行可能な形に変換する言語変換装置および言語変換プログラムに関する。
【背景技術】
【０００２】
プログラマブルコントローラ（Programmable Logic Controller、以下、単に「ＰＬＣ」という）は、シーケンス制御プログラムを実行し、制御対象機器を制御するものである。このプログラマブルコントローラが実行するシーケンス制御プログラムとしては、図７に示すように、例えばＰＣ用言語としての表現依存部（ニーモニック記述、ラダー図、ファンクションブロック図、ＳＦＣ図（Sequential Function Chart）、ディシジョンテーブル、等）とマシン語としての機械依存部との間に中間言語としての関数型制御言語（Functional Control Language、以下「ＦＣＬ」という）がある。
【０００３】
このＦＣＬは、シーケンス制御プログラムを関数型のプログラム構造で表現した言語である。ＦＣＬでは、図８に示すように、一つの機能を引数Ａｒ１、Ａｒ２、Ａｒ３、・・・を持つ関数式Ｆで表している。また、別の関数式を関数式Ｆの引数とすることができる。よって、ある関数式と、そのある関数式の引数（この中には関数式も含まれる）との関係をツリー構造（機能構造）として二次元的に表現することができる。
【０００４】
例えば、図９では、関数Ａが関数Ｂと関数Ｃを引数とし、関数Ｂは引数ｖおよびｗを有し、関数Ｃは引数ｘおよび関数Ｄを引数として有し、関数Ｄは引数ｙおよびｚを有すること、すなわち、下記の式に対する２次元構造が表現されている。
（Ａ  （Ｂ  ｖ  ｗ）  （Ｃ  ｘ  （Ｄ  ｙ  ｚ）））
例えば、特許文献１および２には、関数型言語の実行方式として、命令スタックとデータスタックを用いて演算を実行する方式が示されている。
【０００５】
この命令スタックとデータスタックを用いて演算を実行する方式の場合、当然のこととして、命令スタックとデータスタックという手段が必要となり、それらの手段を持たない装置（例えば、手続き型の命令処理を実行する装置）では、その方式の実行が困難あるいはその方式をエミュレーションするために処理性能が低下するという問題がある。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開平２−２３０４２６号公報
【特許文献２】特開平１−２４３１２６号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
本発明は、命令スタックとデータスタックを持たない装置（例えば、手続き型の命令処理を実行する装置）において、関数型制御言語を実行することを可能とした言語変換装置および言語変換プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００８】
提案する言語変換装置は、関数型言語で記述された制御処理プログラムを手続型の命令処理を行なう装置で実行可能な言語形式に変換する。この言語変換装置は、関数型言語の命令／変数オペランドの各要素の配列を記憶した関数型言語記憶部と、上記配列の各要素を取得し、それぞれをノードとしたツリー構造を作成し、ツリー構造記憶部に出力するツリー構造作成部と、上記ツリー構造中の子供ノード持たないノードであるリーフ以外のノードにインスタンス名を付与するインスタンス名付与部と、上記インスタンス名を付与されたツリー構造に対して、子供ノードがリーフしかないノードを見つけ、そのノードに記述された関数を呼び出し、その呼び出した結果の代入文を、代入先をそのノードに付与されたインスタンス名として作成し、手続型言語の命令群を記憶する手続型言語記憶部に出力する代入文作成部と、上記手続型言語記憶部に出力したノードの子供ノードのすべてを上記ツリー構造中から削除する削除処理部と、を有し、上記ツリー構造が１つのノードになるまで、上記代入文作成処理および上記削除処理を繰り返すものである。
【発明の効果】
【０００９】
提案する言語変換装置によれば、関数型言語の命令／変数オペランドの各要素の配列から生成されたツリー構造を用いて、ネストされた子供の関数が命令の実行順序で親関数の前に、代入文作成部および削除処理部による操作によって並び換えられ、親関数は、子供関数の実行結果が代入されたオペランド（インスタンス名が付けられた変数）を用いて実行される。このような並び換えにより、命令スタックとデータスタックを持たない装置（例えば、手続き型の命令処理を実行する装置）において、関数型制御言語を実行することが可能となる。
【図面の簡単な説明】
【００１０】
【図１】本発明の一実施形態に係る言語変換装置の構成を示すブロック図である。
【図２】関数型言語（ＦＣＬ）格納装置に格納されるＦＣＬの式に対応する配列の一例を示した図である。
【図３】二次元構造格納装置に格納されるツリー構造の一例を示した図である。
【図４】手続型言語格納装置に格納される手続型言語の命令群の一例を示した図である。
【図５】関数型言語（ＦＣＬ）格納装置に記憶された配列の内容から、ツリー構造を作成する処理のフローチャートである。
【図６】本実施形態の言語変換処理のフローチャートである。
【図７】関数型制御言語の位置付けを示す図である。
【図８】関数型制御言語の基本構造を示す図である。
【図９】関数型制御言語の二次元機能構造の一例を表現した図である。
【発明を実施するための形態】
【００１１】
以下図面に基づいて、本発明の実施形態について詳細を説明する。
図１は、本発明の一実施形態に係る言語変換装置の構成を示すブロック図である。例えば、図の各ブロックはハードウェアあるいはソフトウェアとして実現される。
【００１２】
図１に示すように、言語変換装置は、関数型言語（ＦＣＬ）格納装置１１と、二次元構造（ツリー）変換部１２と、二次元構造格納装置１３と、関数名−インスタンス名作成部１４と、命令並び換え部１５と、手続型言語格納装置１６と、を有する。
【００１３】
関数型言語（ＦＣＬ）格納装置１１は、ＦＣＬの命令・変数オペランドを配列として格納したメモリである。
例えば、ＦＣＬの下記式に対して、図２に示すような配列が、関数型言語（ＦＣＬ）格納装置１１に格納される。
（Ａ  （Ｂ  ｖ  ｗ）  （Ｃ  ｘ  （Ｄ  ｙ  ｚ）））
上式では、Ａ、Ｂ、Ｃ、Ｄが関数であり、ｖ、ｗ、ｘ、ｙ、ｚが引数である。図２に示すように、関数を示す変数は開き括弧“（”とともに、関数型言語（ＦＣＬ）格納装置１１の配列の要素に格納するようにしている。また、関数終了子は閉じ括弧“）”として、引数（オペランド）はそのまま、配列の要素に格納するようにしている。
【００１４】
二次元構造（ツリー）変換部１２は、関数型言語（ＦＣＬ）格納装置１１に記憶された配列の内容を、その配列の各要素を節（以下、「ノード」という）としてツリー構造化する。
【００１５】
ノードは、図３に示すように、ノード名称、インスタンス名、子供ノードへのポインタ、次ノードへのポインタ、の各項目を有する。ある関数は、別の関数および変数オペランドを引数とすることができる。呼び出し元の関数からその引数をポイントするときは、“子供ノードへのポインタ”に値を設定する。一方、呼び出し元の関数が同一である引数間では、“次ノードへのポインタ” に値を設定することで、自分に続く引数を指定する。
【００１６】
二次元構造（ツリー）変換部１２は、ツリー構造化に際し、関数部を親のノード、引数部を子供のノードにする。二次元構造（ツリー）変換部１２の処理結果は、二次元構造格納装置１３に出力される。
【００１７】
関数名−インスタンス名作成部１４は、二次元構造格納装置１３の格納内容を参照して、そのツリー構造の末端部（すなわち、子供ノードを持たないノード、以下、このようなノードを「リーフ」という）以外のノードにツリー内での固有の名称（以下、「インスタンス名」という）を付ける。この処理後は、リーフのインスタンス名のみが空欄となる。
【００１８】
図３に、二次元構造格納装置に格納されるツリー構造の一例を示す。図３では、インスタンス名を“ＩＮＳＴ＿”＋“（自動採番により割り振られた）番号”の形式にしているが、各関数を識別可能な任意の方法によりインスタンス名を付与可能である。また、図３のような二次元構造（ツリー構造）を表現するのに、ＸＭＬ（Extensible Markup Language）で記述されたテキストによるデータ構造を使用することができる。ＸＭＬの場合、ツリー構造データの追加／削除／検索などの操作を容易に行なうことができる。
【００１９】
命令並び換え部１５は、二次元構造格納装置１３に格納されたツリー構造を末端に向かう方向に順にたどって、子供ノードがリーフしかないノードを見つけ、その子供ノードがリーフしかないノードについて、ノードに記述された関数を呼び出して、その関数の値を代入する代入文を作成して、手続型言語格納装置１６に格納する。なお、代入先はそのノードのインスタンス名とする。
【００２０】
続いて、命令並び換え部１５は、上記処理で手続型言語格納装置１６に格納したノードの子供ノードをすべて削除する。そして、最上位の親ノードまで戻り、同様の処理を繰り返す。ツリー構造上のノードの数が１つになるまでこの処理を行なう。
【００２１】
命令並び換え部１５による以上の操作によって、ネストされた子供の関数が命令の実行順序で親関数の前に並び換えられ、親関数は、子供関数の実行結果が代入されたオペランド（インスタンス名が付けられた変数）を用いて実行される。
【００２２】
図４に、手続型言語格納装置１６に格納される手続型言語の命令群の一例を示す。図４では、手続型の命令処理を行なう装置で実行可能な命令として、ＰＡＳＣＡＬ言語の場合が示されている。この言語では、代入を“：＝”で表し、関数呼び出しを“関数名（引数１，引数２，．．．）”で表している。
【００２３】
図５は、関数型言語（ＦＣＬ）格納装置１１に記憶された配列の内容から、ツリー構造を作成する処理のフローチャートである。このフローチャートの処理は、二次元構造（ツリー）変換部１２によって実行される。
【００２４】
図５のステップＳ１において、ルートノード（一番上位の要素：処理を再帰的に実行するためのダミーノード）を生成し、そのルートノードを現在処理中ノードに設定する。すなわち、そのルートノードのアドレスを現在処理中ノードポインタに設定する。
【００２５】
続く、ステップＳ２で、関数型言語（ＦＣＬ）格納装置１１に記憶された配列の現在位置からデータが読み出される。そして、ステップＳ３でデータの種類が判定される。
読み出されたデータ（配列の要素）が開き括弧“（”＋“文字（列）”の形式をしていれば、ステップＳ３において、そのデータは関数であると判定される。この場合、ステップＳ４において、その関数の名称（“文字（列）”）をノード名称に設定したノードが新規作成され、ステップＳ７に進む。
【００２６】
読み出されたデータ（配列の要素）が “文字（列）”の形式をしていれば、ステップＳ３において、そのデータはオペランドであると判定される。この場合、ステップＳ５において、そのオペランドの名称（“文字（列）”）をノード名称に設定したノードが新規作成され、ステップＳ６において、その新規作成されたノードの子供ノードへのポインタに“ＮＵＬＬ”が設定され、ステップＳ７に進む。
【００２７】
ステップＳ４またはステップＳ６から制御を渡されたステップＳ７では、新規作成したノードを現在処理中ノードに設定する。
ステップＳ７に続くステップＳ８では、新規作成したノードに対する次ノードあるいは子供ノードへのポインタの設定処理が実行される。
【００２８】
すなわち、現在処理中ノードが関数に対応したものであり、かつ、新規作成したノードが関数に対応したもののときに、新規作成したノードの次ノードへのポインタに“ＮＵＬＬ”を設定し、現在処理中ノードがオペランドに対応したものであり、かつ、新規作成したノードがオペランドに対応したもののときに、新規作成したノードの次ノードへのポインタに“ＮＵＬＬ”を設定し、現在処理中ノードがオペランドに対応したものであり、かつ、新規作成したノードが関数に対応したもののときに、新規作成したノードの次ノードへのポインタに“ＮＵＬＬ”を設定し、現在処理中ノードが関数に対応したものであり、かつ、新規作成したノードがオペランドに対応したもののときに、新規作成したノードの子供ノードへのポインタに“ＮＵＬＬ”を設定する処理が実行される。そして、ステップＳ２に戻り、次のデータ（配列の要素）の読み込み処理が実行される。
【００２９】
一方、ステップＳ２で読み出されたデータ（配列の要素）が閉じ括弧“）”の形式をしていれば、ステップＳ３において、そのデータは関数終了子であると判定される。この場合、ステップＳ９において、そのときの現在処理中ノードの次ノードへのポインタに“ＮＵＬＬ”を設定し、続くステップＳ１０で、その終了した関数のノードを現在処理中ノードに設定する。そして、ステップＳ２に戻り、次のデータ（配列の要素）の読み込み処理が実行される。
【００３０】
図６は、本実施形態の言語変換処理のフローチャートである。このフローチャートは図１の言語変換装置の各ブロックによって実行される。
この処理に先立って、関数型言語（ＦＣＬ）格納装置１１には、ＦＣＬの命令・変数オペランドが配列として予め格納されているものとする。
【００３１】
図６のステップＳ２１において、二次元構造（ツリー）変換部１２によって、関数型言語（ＦＣＬ）格納装置１１に記憶された配列の内容が、その配列の各要素をノードとしてとしてツリー構造化される。その詳細は図５のフローチャートに示した通りである。なお、その二次元構造（ツリー）変換部１２による処理結果（ツリー構造）は、二次元構造格納装置１３に格納される。
【００３２】
続く、ステップＳ２２では、関数名−インスタンス名作成部１４によって、二次元構造格納装置１３の格納内容を参照して、そのツリー構造のリーフ以外のノードにインスタンス名が付与される。
【００３３】
そして、ステップＳ２２に続くステップＳ２３で、ノード総数カウント処理がノード総数カウント部（不図示）によって行われる。これは、ツリー構造のその時点におけるノード総数をカウントする処理である。
【００３４】
続くステップＳ２４では、ステップＳ２３でカウントされたノード総数が“１”に等しいかどうかが判定される。
ステップＳ２４でノード総数が“１”に等しいと判定された場合、一連の処理を終了する。
【００３５】
ステップＳ２４でノード総数が“１”に等しくないと判定された場合、ステップＳ２５で、命令並び換え部１５によって、二次元構造格納装置１３に格納されたツリー構造が末端に向かう方向にたどられて、子供ノードがリーフしかないノードが検索される。この検索の結果として、子供ノードがリーフしかないノードが見つけられ、その子供ノードがリーフしかないノードについて、ノードに記述された関数が呼び出されて、その関数の値を代入する代入文が、代入先をそのノードのインスタンス名として作成されて、手続型言語格納装置１６に格納される。
【００３６】
続く、ステップＳ２６で、命令並び換え部１５によって、上記処理で手続型言語格納装置１６に格納したノードの子供ノードがすべて削除される。そして、ステップＳ２３に戻り、同様の処理を繰り返す。ツリー構造上のノードの数が１つになるまでこの処理を行なう。
【００３７】
関数型言語の命令／変数オペランドの各要素の配列から生成されたツリー構造を用いて、ネストされた子供の関数が命令の実行順序で親関数の前に、命令並び換え部１５による以上の操作によって並び換えられ、親関数は、子供関数の実行結果が代入されたオペランド（インスタンス名が付けられた変数）を用いて実行される。
【００３８】
このような並び換えにより、命令スタックとデータスタックを持たない装置（例えば、手続き型の命令処理を実行する装置）において、関数型制御言語を実行することが可能となる。
【符号の説明】
【００３９】
１１  関数型言語（ＦＣＬ）格納装置
１２  二次元構造（ツリー）変換部
１３  二次元構造格納装置
１４  関数名−インスタンス名作成部
１５  命令並び換え部
１６  手続型言語格納装置
【図１】
0005541102.tif 000002
【図２】
0005541102.tif 000003
【図３】
0005541102.tif 000004
【図４】
0005541102.tif 000005
【図５】
0005541102.tif 000006
【図６】
0005541102.tif 000007
【図７】
0005541102.tif 000008
【図８】
0005541102.tif 000009
【図９】
0005541102.tif 000010