ellisp

出典: 謎の百科事典もどき『エンペディア(Enpedia)』
ナビゲーションに移動 検索に移動

ellispは、仮想プログラミング言語の一種。仮想機械上の仮想言語に落とされ、仮想機械上で実行される。
もともとは漢字ローマ字交じりテキストを処理するために、1992年ごろに島田正雄によって実装された。 「lisp(プログラミング言語)」には「舌足らずの」の意があり、「ellipse(楕円)」には「不足した」の意味があるため、「ちょっと足りないおバカな言語」ということで命名された。

概要[編集]

もともとのアイデアは数学者(数学基礎論)の島内剛一による「島内式ローマ字かな変換」である。

特徴としては(Prologと同じく)「実行順序というものがない」という点で、制禦構造らしきものは制禦型の

  • [構文要素1] - "{"マッチングパターン1" | "マッチングパターン2"}" - [構文要素2];

しかない。従って ellisp のコードはただ結合するだけで同じように動く。
解釈処理系をいじることで いろいろと省略できる。[1]

プログラミング構文は基本的には

  • 制禦用
  • 辞書用

のふたつがあり、同じ仮想機械の実行用の構造(一つしかない)に落ちるが、実行用のデータとお辞書用のデータを統合するためのテーブルが必要である。

制御表現[編集]

  • [構文要素1] - "{"マッチングパターン"|"マッチングパターン2"}" - [構文要素2];,

は、

  • "{"マッチングパターン1" | "マッチングパターン2"}"

の部分を {"マッチングパターン1" | "マッチングパターン2"}" と書こうが

  • {"マッチングパターン1" | "マッチングパターン2"}"
  • {マッチングパターン1" | "マッチングパターン2}
  • {マッチングパターン1 | {マッチングパターン1"|"マッチングパターン2}
  • "マッチングパターン"
  • {マッチングパターン}

のどれを使ってもよく、マッチングパターン文字列を省略して

  • [構文要素1] - [構文要素2];

と書いても問題なく通る。ただし、

  • [構文要素1] - [構文要素2];
  • [構文要素2] - [構文要素1];

といった記述をすると、スタックオーバーフローで実行時に あっという間に落ちるという剣呑な言語(というか、処理系側の事情である)であり、「同一局面ではない」ことを いちいちチェックしていると実行の手間がかかるので、内部表現に落とすときに構文チェックでハネるのが望ましいが、それを実行時にやっていると効率が悪そうなので、「そのうちコンパイラを強化すればいいや」と居直った。
将棋の局面だったら線形順序関係はそれほど気にしなくていい(というか、判定が難しい(「千日手」は直近の過去の数局面に対する対策のチェックだけで済む)。 コンピュータ将棋の場合、

  • [対局開始] - [先手];
  • [開局] - [後手];
  • [先手] - [着手];
  • [後手] - [着手];
  • [切れ負け] - [終局];
  • [反則負け] - [終局]; // 二歩など
  • [負けました/ありません] - [終局]; // 「あぁ、錯覚いけない。よく見るよろしい」という名言がある。

で済む話であり、[着手]と[応手]の間に思考ルーチンが入る。

辞書表現[編集]

何万語もある辞書を ellisp によって記述したのでは堪ったものではない。そこで、辞書記述用の表記がある。
たとえば「高見の見物(名詞)」であれば、

  • {たかみ|高見}の{けんぶつ|見物}[名詞];

と記述する。単語の文法属性までの部分から「たかみのけんぶつ」という見出し語と「高みの見物」という本表記に分けて個別に処理する。なお、文法属性は ellisp の開始属性と終端属性との関連を示すテーブルとするが、形容詞・動詞の場合には「語幹の部分を切出すための、連体形の活用語尾」も含めてテーブルとして持つ。
現在のパソコンの主記憶領域は充分に広いため、「漢字かな交じりの日本語テキストを読みに開いたり、HTML のルビ付き文書に変換する」くらいは造作もない。

  • 見出語と表記
  • 品詞分類

に、セミコロンがついただけのものである。品詞分類の後に辞釈が入ることもある。すなわち、

  • {見出語と表記}(品詞分類)辞釈; //コメント

というデータの並びである。実行順序がないので、見出語の部分の「読み」だけで整列してよい[2]

ふりがなの表記[編集]

文字列の表記においては、「読み」と「表記」、「どこからどこまでに、どのようなルビを振るか」「行末禁則と競合しないか」といったことをコンピューターに正確に伝えなければならない。そのため、ellisp は"{}|"を用いる形式を取っている。
たとえば "文字列"は"{文字列|もじれつ}"などと表記する。

具体例[編集]

ローマ字かな変換であれば、

  「[文字] - {"s"|} - [サ行音];」 

あるいは

  「[文字] - "{s|}" - [サ行音];」 

と定義としておいて、

   [サ行音] - {"ha"|"シャ"} - [文字の終わり];
   [サ行音] - {"hi"|"シ"} - [文字の終わり];
   [サ行音] - {"hu"|"シュ"} - [文字の終わり];
   [サ行音] - {"he"|"シェ"} - [文字の終わり];
   [サ行音] - {"ho"|"ショ"} - [文字の終わり];

などとしておけば、「sa・si・su・se・so」と「sha・shi・shu・she・sho」の処理は統合できる。これにより、「どの候補を選択するか」という問題に帰着するため、あとはユーザに選んでもらえばいいし、「このユーザはどのルールを優先するか?」はパソコンが学習できる。 「sya・syu・syo」や「tsu」「cha・chi・chu・che・cho」も同様に扱える。

「Microsoft IME」はローマ字かな変換において「接続テーブル法」を使っている模様である(「ローマ字のオプション」の項を参照のこと)。 ところが、ローマ字かな変換だけでも「26文字×26文字」のテーブルには収まりきれず、しかもテーブルの中身はスパース(スケスケ)であるため、保守の手間が半端ではない。それゆえ現今のローマ字かな変換システムおよび IME の変換精度は低いままである。 その点、島内式であれば文字列のパターンマッチングと属性定義によって関連のあるところだけを定義すればいいため、可読性が高くコンパクトな記述になることが期待される。

なお、マッチングパターン文字列を逆に解釈すると、同じ記述が「かなローマ字変換」にも使えることを指摘しておく。 主に ひらがな表記の一部のみを示しておく。ひらがなでは音引き(「ー」)が使われることが少ないので、省略する。

   [文字] - {"a"|"あ"} - [文字の終わり];
   [文字] - {"i"|"い"} - [文字の終わり];
   [文字] - {"u"|"う"} - [文字の終わり];
   [文字] - {"e"|"え"} - [文字の終わり];
   [文字] - {"o"|"お"} - [文字の終わり];
   [文字] - {"k"|} - [カ行音];
   [文字] - {"k"|"く"} - [文字の終わり];
   [カ行音] - {"a"|"か"} - [文字の終わり];
   [カ行音] - {"i"|"き"} - [文字の終わり];
   [カ行音] - {"u"|"く"} - [文字の終わり];
   [カ行音] - {"e"|"け"} - [文字の終わり];
   [カ行音] - {"o"|"こ"} - [文字の終わり];
   [カ行音] - {"ya"|"きゃ"} - [文字の終わり];
   [カ行音] - {"yu"|"きゅ"} - [文字の終わり];
   [カ行音] - {"yo"|"きょ"} - [文字の終わり];
   [文字] - {"c"|} - [C行音];
   [文字] - {"c"|"く"} - [文字の終わり];
   [C行音] - {"a"|"か"} - [文字の終わり];
   [C行音] - {"i"|"スィ"} - [文字の終わり];
   [C行音] - {"i"|"ち"} - [文字の終わり];
   [C行音] - {"i"|"し"} - [文字の終わり];
   [C行音] - {"i"|"サイ"} - [文字の終わり];
   [C行音] - {"u"|"く"} - [文字の終わり];
   [C行音] - {"e"|"せ"} - [文字の終わり];
   [C行音] - {"o"|"こ"} - [文字の終わり];
   [文字] - {"g"|} - [ガ行音];
   [文字] - {"g"|"ぐ"} - [文字の終わり];
   [ガ行音] - {"a"|"が"} - [文字の終わり];
   [ガ行音] - {"i"|"ぎ"} - [文字の終わり];
   [ガ行音] - {"u"|"ぐ"} - [文字の終わり];
   [ガ行音] - {"e"|"げ"} - [文字の終わり];
   [ガ行音] - {"o"|"ご"} - [文字の終わり];
   [ガ行音] - {"ya"|"ぎゃ"} - [文字の終わり];
   [ガ行音] - {"yu"|"ぎゅ"} - [文字の終わり];
   [ガ行音] - {"yo"|"ぎょ"} - [文字の終わり];
   [文字] - {"s"|} - [サ行音];
   [文字] - {"s"|"す"} - [文字の終わり];
   [サ行音] - {"a"|"さ"} - [文字の終わり];
   [サ行音] - {"i"|"し"} - [文字の終わり];
   [サ行音] - {"u"|"す"} - [文字の終わり];
   [サ行音] - {"e"|"せ"} - [文字の終わり];
   [サ行音] - {"o"|"そ"} - [文字の終わり];
   [サ行音] - {"ya"|"しゃ"} - [文字の終わり];
   [サ行音] - {"yu"|"しゅ"} - [文字の終わり];
   [サ行音] - {"yo"|"しょ"} - [文字の終わり];

実装[編集]

記述言語[編集]

日本語処理の項を参照されたい。

構成[編集]

仮想マシンではあるが、日本語処理などの大規模処理に対応する必要が生じ、データベースとのインターフェースが欠かせなくなくなる。

利点と弱点[編集]

利点は、仮想言語の実行エンジンの動作が単純であるおと。 弱点は実際的な部分に多くあり、

  • 辞書引きが大量に発生するので、速い検索アルゴリズムが必要であり[3]、辞書を二次記憶に置くと遅くなること[4]
  • 扱うデータがネットワーク構造であったため、ポインタ操作とか再帰とかが扱えるプログラマでないと扱いが難しかった。この点は C 言語が楽ではあったが、C ではメモリリークやワイルドポインタのリスクが高く動作が安定しないうえに、catch & throw がないのでコードがややこしくなった。この点 Java は安心だが、いままでポインタやらハンドルで書いていたものを「参照だけを使って書け」ということになって普通のプログラマだと頭を抱える。
  • 入出力部分は実務の要求に応えるために、その業務ごとにツールともどもコードを書かねばならなくなって、それが大変。

などがある。辞書に関していうと、日本語処理は三千語くらいの辞書があればまずまず使えるが、さらに精度を上げようと思うと

  • 一万語 ~ 一万五千語 - 個人が使うレベルか、分野別の辞書
  • 三万語 ~ 三万五千語 - 商用のかな漢字変換システムの辞書
  • 五万語 ~ 五万五千語 - 都道府県・市郡区や、一般的な姓は口語的に崩れた語まで含む。
  • 八万語 ~ - 山名、蚊船名、地名、企業名、人名 などの固有名を網羅するとこのラインを越える。

くらいあるので、まともに管理しようとするとデータベースを用いた専用の管理しすてむがある。国語辞典を編纂しようと思うと専用の編集システムと辞書管理者の頭数が要る。実体験でいうと、(開発と並行して行うなら)一万語でも相当にキツく、下請けに出そうとして辞書管理システムを開発したが、管理者が辞めてしまって頓挫した。「御岳山」には「おんたけさん」「みたけさん」があり、「武蔵御岳」は「むさしみたけ」で「木曽御岳」は「きそおんたけ」である。

関連項目[編集]

脚注[編集]

  1. ローマ字入力の「島内式ローマ字かな変換」の項を参照のこと
  2. このあたりの話は日本語の辞書を参照のこと。
  3. これについてはトリプル配列法がある。
  4. 現在はギガ単位のメモリ空間があるからマシだが、主記憶が 384K とかいった時代には RAM ディスクに辞書部を置いて速度を稼いでいた。