オートマトンは、IIIMF ランゲージエンジン Wnn8LE など (Wnn8LE) のローマ字かな変換を実現している機能で、変換内容を設定した表 (変換表) を変えることで任意の変換にすることができます。また、このシステムには、これと同一の機能を持ったオートマトンライブラリ (日本語入力ライブラリ (libwnn) の romkan_ で始まる関数) があり、多種多様な変換プログラムに応用できます。
オートマトンは、変換表に従って直列に結ばれた 3 つの変換 (順に、前処理、本処理、後処理) を行い、その最終結果を出力します。3 つの処理操作は、それぞれの変換表に基づいて変換を行います。また、オートマトンは、モード機能を持っています。モードを切り替えることにより、3 つの処理で使用する表の組み合わせを動的に変更できます。このモードの設定、切り替えコードの設定も変換表で行います。
変換表が、テキストファイルであるため、表は容易に変更でき、しかも任意の変換表に変更できます。また、1 つの変換を行った後、次の変換を行うまでは、 BS (バックスペース) により変換の 1 つ前の状態に戻すことができます。
Wnn8LE のローマ字かな変換では、本処理で「英大文字からひらがな」の変換しか行えませんが、前処理で「英大文字から英大文字」、「英小文字から英大文字」の切り替え、また後処理では「ひらがなからひらがな」、「ひらがなからカタカナ」、「ひらがなから半角カタカナ」の切り替えを行うことにより、ローマ字かな変換の入力と出力のさまざまな状況に対処しています。
オートマトンは次のように処理されます。
入力。英 (半角) の大文字と小文字
前処理。小文字は大文字に変換
本処理。英大文字からひらがなへの変換表に基づいて変換
後処理。ひらがなを必要に応じてカタカナや半角カナに変換
出力。
オートマトンは、変換表として次の表を使用します。
モード定義表
モード宣言や使用する対応表を指定する表。ファイル名は mode
前処理表
前処理で使用する対応表。1 で始まるファイル名
本処理表
本処理で使用する対応表。2 で始まるファイル名
後処理表
後処理で使用する対応表。3 で始まるファイル名
モード定義表には、モードの宣言、各モードで使用する対応表の組み合わせとその決定規則を記述します。
対応表には、入力コードと出力コードとの対応が記述されます。対応表は、前処理、本処理、後処理の 3 つに分かれ、それぞれ、任意の数の表を使用できます。
Wnn8LE は、モード定義表を以下の順番で探します。
Wnn8LE 初期化ファイル uumrc の setrkfile エントリによる指定
ファイル名 /usr/lib/wnn/ja_JP/rk/mode
以下のモード定義表と対応表の説明では、次の表記法を使用しています。
. . . は、0 回以上の繰り返し
. . . . . . は、1 回以上の繰り返し
[ ] は、省略可能
モード定義表には、モード宣言、各モードで使用する対応表の組み合わせとその決定規則、モード表示文字列モード表示文字列が記述さます。
モード定義表は、次の 1、2、3、4 で構成されます。ただし、行の先頭または空白文字 (タブを含む) に続き、しかもエスケープされていないセミコロン (;) から行末までの文は、注釈文として扱われます。
特殊文字としては、以下に示すものがあります。
環境変数 HOME を表す
モード定義表の存在するディレクトリを表す
標準設定がしてある変換表が存在するディレクトリ (/usr/lib/wnn/)
user がユーザー名ならば、そのユーザーのログインディレクトリ名を表す。user の指定がなければ、自分のログインディレクトリ名を表す。
モード宣言の書式は、次のとおりです。
mode_name は、英数字からなる文字です。[initial_status] は、on または off を指定します。省略時は、off です。
モード宣言は、そのモードを使用する前に行います。
対応表の検索指定の書式は、次のとおりです。
モード定義表で指定された対応表がモード定義表と同じディレクトリにない場合、探しにいく directory を指定します。directory は、空白で区切って複数指定できます。search は、対応表の指定より前に指定してください。
対応表を検索するために既に格納されているディレクトリ名を削除し、引数に指定された directory を格納します。directory は、空白で区切って複数指定できます。search は、対応表の指定より前に指定してください。
指定方法は、次の 3 つがあります。
対応表のファイル名またはモード表示文字列 . . . . . .
(if 条件式 対応表の指定またはモード表示文字列 . . .)
(when 条件式 対応表の指定またはモード表示文字列 . . .)
対応表は、(1)、(2)、(3) のいずれかで始まるファイル名を指定します。パスによる指定もできます。モード表示文字列は、そのときのモードを表す二重引用符 (“) で囲んだ文字列です。
“string“
変換が ON のときのモード表示文字列を表します。
(on_dispmode “string“)
変換が ON のときのモード表示文字列を表します。
(off_dispmode “string“)
変換が OFF のときのモード表示文字列を表します。
(on_unchg)
変換が ON のときのモード表示文字列をモード変換する前と同じモード表示文字列を表します。
(off_unchg)
変換が OFF のときのモード表示文字列をモード変換する前と同じモード表示文字列を表します。
Wnn8LE では、この文字列がモード表示に使用されます。
オートマトンライブラリは romkan_dispmode() によって、この文字列を取り出すことができます。ただし、モード定義表にあるモード時のモード表示文字列が複数あるように記述されている場合、最後のものだけが有効です。
(2)、(3) は、条件によって選択する対応表を変えたいときに使用します。(2) の if 文 は、その条件式の結果が真ならば、その if 文内の指定を参照し、if 文の次の指定は参照しません。条件式が偽ならば、すぐ if 文を抜け出して if 文の次の指定を参照します。
(3) の when 文は、その条件式の結果が真ならば、その文内の指定を参照し、偽ならば参照しません。しかし、if 文と異なり、条件式の真偽にかかわらず when 文の次の指定を参照します。
なお、(2)、(3) で対応表を指定する場合には、(2) または (3) を再帰的に定義できます。
条件式には次のうち 1 つを記述します。
モード名 | モードの状態が on のとき真 |
(and 条件式 条件式) | 2 つの条件式が真のとき真 |
(or 条件式 条件式) | どちらか条件式が真のとき真 |
(not 条件式) | 条件式が偽のとき真 |
(false) | 常に偽 |
(true) | 常に真 |
たとえば、モード定義に (defmode kana) と (defmode romajikana) があるとき、(and kana romajikana) は、双方のモードが on のとき真になります。
またたとえば、(ここでは、条件式を○◎●で表し、変換表の名前を ABC. . . で表すという規則のもとに)
(when ○ A (if ◎ B) C) (if ● D) E
と書かれていたとします。そして、条件式○◎●共に成り立っているとします。この並びを最初から見ていきます。まず、(when ○ A (if ◎ B) C) とあります。ここでは○は成り立つので、「A (if ◎ B) C」という並びを見ます。はじめに、表 A を選択します。
次に、(if ◎ B) がきて、しかも◎が成り立つので、表 B を選択します。この文は if 文で、しかも条件式が成り立っているので、現在注目している並び「A (if ◎ B) C」のうち残りの部分は見ません。これで、「A(if ◎ B) C」という並びを見終えたことになりますが、この並びを含んでいたものは、when 文なので、さらに「(when ○ A (if ◎ B) C) (if ● D) E」という並びの、残りの部分を見ます。
次に書かれているのは、(if ● D) です。●が成り立つので、表 D を選択しますが、if 文なので、「(when ○ A (if ◎ B ) C ) (if ● D ) E」という並びのうち、残りの部分は見ません。こうして、表 A、B、D が選択されます。
次に、Wnn8LE が使用するモード定義表を例として示します。
このモード定義表では、3 のモードが定義されています。その後の 2A_CTRL から最後までが使用する対応表とモード表示文字列の指定です。モードが変わるごとに、この表を見て、上記のようにして使用する表の選択を行います。
(defmode romkan) (defmode katakana) (defmode zenkaku) 2A_CTRL (if romkan 1B_TOUPPER 2B_ROMKANA 2B_JIS (if (not katakana) "[あr]") (if zenkaku 3B_KATAKANA "[アr]") 3B_HANKATA "[アイr]") ;「ア」と「イ」は半角のカタカナを示す 2B_DAKUTEN (if (not katakana) 1B_ZENHIRA (if zenkaku 3B_ZENKAKU "[あ ]") "[Aあ]") (if zenkaku 1B_ZENKATA 3B_ZENKAKU "[ア ]") "[アイA]" ;「ア」と「イ」は半角のカタカナを示す
初期状態は、romkan、katakana、zenkaku のモードすべてが off です。このとき表は、始めに 2A_CTRL を選択します。romkan が off なので、次の if 文は参照ません。そして、2B_DAKUTEN を選択します。次の if 文の条件式 (not katakana) は、katakana が off なので真となります。そこで if 文内を参照し、1B_ZENHIRA を選択します。次に if 文内の if 文を参照します。この if 文では zenkaku が off になっているため条件式が偽となります。したがって、この if 文は参照しません。
次に、モード表示文字列「[Aあ]」を選択します。残りの変換表並びは見ません。
対応表には、前処理、本処理、後処理のそれぞれが行う変換データ (入力コードと出力コードとの対応) が記述されます。
前処理、後処理は、本処理の補助という位置付けがなされています。このことから、前処理、後処理の対応表には次の制限が課せられます。
下記の (2) の記述ができません。また、(1) の入力コードと出力コードには、それぞれ評価すると文字になる式が 1 つだけ書けます。バッファー残りには書けません。
下記の (2) の記述ができません。また、(1) の入力コードには、評価すると文字になる式が 1 つだけ書けます。バッファー残りには書けません。
対応表の行のうちのある行は、次の (1) から (3) のうち 1 つか、または空行です。この繰り返しで対応表が構成されます。
入力コード [出力コード [バッファー残り]]
入力コード 機能
変数宣言
これらは、2 行にわたって記述することはできません。改行または空白文字 (タブを含む) に続き、かつエスケープされていないセミコロン (;) から行末までの文は、注釈文として扱われます。
出力コードの省略、およびバッファー残りの省略は NULL 文字列の文として扱われます。 入力コード、出力コード、およびバッファー残りに記述できるのは、「評価すると文字になる式」と「評価すると文字列になる式」を空白なしに並べたものです。
ここで、評価すると文字式または文字列になる式とは、その式によって文字あるいは文字列に置き換わる、そのような式のことです。
「評価すると文字になる式」には、次のものがあります。
文字表記を下記に示します (「評価すると文字列になる式」の文字表記とは異なります)。
「(」、「)」、「'」、「"」、「\」、「;」、「 」(空白文字) を除く文字。
「'」、「\」、「^」を除く文字。
コントロール文字を表します。文字は ASCIIコードの 32 から 126 の文字または英小文字です。「^?」は DEL コードを表します。
「\」の次の文字を表します。この式でいう文字からは、数字と「o」「d」「x」は除きます。「\n」、「\t」、「\b」、「\r」、「\f」 は C 言語のエスケープ符号列と同じです。「\e」、「\E」は ESC 文字を表します。他の文字は、その文字自身を表します。
その 8 進コードを持つ文字を表します。
その 8 進コードを持つ文字を表します。
その 10 進コードを持つ文字を表します。
その 16 進コードを持つ文字を表します。
関数名 | 機能 |
---|---|
toupper | 引数が ASCII 英小文字ならば大文字に変える 例: (toupper a) -> A |
tolower | 引数が ASCII 英大文字ならば小文字に変える 例: (tolower A) -> a |
toupdown | 引数が ASCII 英小 (大) 文字ならば大 (小) 文字に変える 例: (toupdown a) -> A (toupdown A) -> a |
tozenalpha | 引数が ASCII 文字ならば対応する全角文字に変える 例: (tozenalpha A) -> A |
tohira | 引数が全角カタカナならばひらがなに変える 例: (tohira ア) -> あ |
tokata | 引数がひらがなならば全角カタカナに変える 例: (tokata あ) -> ア |
tozenhira | 引数が半角カタカナならばひらがなに変える 例: (tozenhira ア) -> あ ; 「ア」は半角カタカナ |
tozenkata | 引数が半角カタカナならば全角カタカナに変える 例: (tozenkata ア) -> ア ; 「ア」は半角カタカナ |
value | 引数の文字コードを実際の数値にする 例: value 0 -> '\x0' value A -> '\xA' value F -> '\xf' |
関数名 | 機能 |
---|---|
+ | 引数の和を値にする 例: (+ あ '256') -> ア (+ 0 (value 3)) -> 3 |
– | 引数の差を値にする |
* | 引数の積を値にする |
/ | 引数の商を値にする |
関数名、機能、宣言名 (defvar) といずれも 一致しない英字で始まる英数字からなる文字列 (変数の項参照)。ただし、'_' も英字とみなします。
評価すると文字列になる式には、次のものがあります。
文字表記を下記に示します (「評価すると文字になる式」 の文字表記とは異なります)。
「"」、「^」、「\」を除く文字
コントロール文字を表します。文字は ASCIIコードの 32 から 126 の文字または英小文字です。^? は、DELコードを表します。
数字と「o」「d」「x」を除く文字。「\n」、「\t」、「\b」、「\r」、「\f」 は C 言語のエスケープ符号列と同じです。
その 8 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) が必要です。
その 8 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) が必要です。
その 10 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) が必要です。
その 16 進コードに相当する文字を表します。後に数字が続く場合はセミコロン (;) が必要です。
" " は空文字列を表します。
関数名 | 機能 |
---|---|
tohankata | 引数が全角ひらがなまたは全角カタカナならば半角カタカナに変える 例: tohankata が -> ガ (半角) |
last= | 最後に照合した文字列の最後の文字と関数の引数 (評価すると文字になる式) が一致するかどうかを検査し、一致する場合 (last= 評価すると文字になる式) は空文字列になる。 例: last= A -> あ ただし、last= は入力コードにだけ記述できる |
todigit | 第 1 引数で与えられたコードを第 2 引数のコードの進法の数に変換する |
dakuadd | 引数の後ろに濁点を付ける |
handakuadd | 引数の後ろに半濁点を付ける |
モード名はモード定義表で宣言された名前にしてください。
関数名 | 機能 |
---|---|
if | 引数であるモードが on なら、(if mode_name) は空文字列になる 例: (if katakana)VU ヴ |
unless | 引数であるモードが off なら、(unless mode_name) は空文字列になる 例: (unless katakana)VU ぶ |
on | 引数であるモードを on にする 例: (on katakana) |
off | 引数であるモードを off にする 例: (off katakana) |
switch | 引数であるモードが on なら off に、off なら on にする 例: (switch katakana) |
ただし、if、unless は、入力コードにだけ記述できます。また、on、off、switch は、本処理表の出力コードにだけ記述できます。
本処理表の出力コードにだけ記述できます。
関数名 | 機能 |
---|---|
allon | すべてのモードを on にする |
alloff | すべてのモードを off にする |
機能には下記の 2 つがあり、それぞれ単独で用いられます。
入力コードの部分のコードが入力されたら、エラーとみなします。
前回のモード定義表を改めて読み込んで変換の再設定を行います。新しい変換表にエラーがあればエラーメッセージを表示したあと、元の変換表の設定に戻します。
list は、その引数の文字を変域とします。
all は、すべての文字を変域とします。
「評価すると文字になる式」として使用する変数とその変域の定義を行います。宣言は、上記の方法で行います。変数表記は、変数名または (変数名. . . . . .) です。文字表記は、「評価すると文字になる式」の文字表記と同じです。
関数は「評価すると文字になる式」または 「評価すると文字列になる式」であるため、(toupper (tolower Y)) と書けます。しかし、次のように評価すると文字列になる関数は他の関数の引数にできません。
(toupper (tohankata か))
(defvar a1 (list K S T H Y R W G Z D B P)) (a1)(a1) っ (a1)
この 2 行は次の記述と同じ変換を行います (これはローマ字かな変換における促音処理です)。
KK | っ | K |
SS | っ | S |
TT | っ | T |
. . . | ||
(中略) | ||
PP | っ | P |
変数は、変数宣言 (defvar) で行った変域の文字を値とします。
変数使用上の注意事項
使用する変数はその表の中において defvar で定義してください。
変数の定義はその表の中全体で有効です。1 つの表で a1 という変数を定義し、別な表で a1 という変数を別様に定義することができます。この 2 つの a1 は別の変数として扱われます。そのとき、逆に 1 つの表の中で同名の変数を 2 度 defvar することはできません。
対応表の1行の中では、同名の変数は常に同じ値を持ちます。
(defvar a1 (list A B)) (a1)(tolower (a1)) 3
この場合、「Aa 」、「Bb」という文字列が「3」に変換されます。「Ab」、「Ba」は変換されません。
入力コードと表の入力コード部との照合は左から行われます。このため、表の入力コード部を左から見ていったとき、ある変数が特定の文字に一致する前に関数の引数として現れることはできません。
(defvar a1 (list a b)) (toupper (a1))(a1) 3
この場合、「Aa」と入力しても、「3」には変換されません。これは、値が特定されていない状態で a1 が (toupper (a1)) に引数として現れるからです。このような設定は、表読み込み時にチェックされます。
変数を出力コード部やバッファー残り部に書く場合も、入力コード部に現れる (つまり、入力コードとの照合で何らかの値を代入される) 変数でなければなりません。
(defvar a1 (list K S)) (defvar a2 (list a)) (a1)(a1) (a2) (a1)
この場合、入力コード部で照合が行われない変数 a2 が出力コード部に現れているので規則 違反になります。
まず、入力されるコードを文字単位にまとめます (2 バイトコードの文字も 1 文字として扱います)。これを入力コードといいます。これは、前処理、本処理、後処理の 3 処理を経て最終出力となります。前処理では、入力コード 1 つに対して出力コード 1 つが対応付けられます。この出力コードが本処理コードの入力コードになります。
前処理表のうち現在使用されている表の入力コードの部分を上から順に見ていきます。最初に実際の入力コードと合致したところで、その行の出力コードの部分に書かれてあるものが出力されます。ただし、表が複数選択されているときは、モード定義表で先に参照されたものから見ていきます。また、実際の入力コードと合致するものが表にないとき (表が 1 つも選択されない時も含む) は、入力コードがそのまま出力されます。これは、本処理、後処理においても同様です。
本処理では、入力コードが表の入力コードの部分と合致する可能性がある (入力コードの部分の先頭から何文字かは一致している状態) 限り、入力コードは、バッファーに追加されます。バッファーに入力コードが追加されるごとに、本処理表の入力コードの部分を上から順に見ていってバッファーと比較されます。ここでバッファーの内容が表の入力コードの部分の最長のものと合致する可能性 (入力コードに部分の先頭から何文字かは一致している状態) があれば、変換未確定という判断のもとに、変換を行わずに次の入力コードを待ちます。
ただし、画面処理などの都合上、バッファー内のコードは未確定文字として出力されます。他に入力エラー、モード変更などを知らせるコードも出力されます。
これらの出力コードは本来の出力コードとは区別され、後処理は行われません。
バッファーの内容が表の入力コードの部分の最長のものと合致したら (同じ長さのものがあれば先に見つかったものと合致します)、その出力コードが出力されます。バッファー残りの部分がなければバッファー内の合致した部分が消され、あれば、バッファー内の合致した部分と入れ替わり、以上の操作が繰り返されます。
表に合致する可能性のあるものが見つからなかった場合、バッファーの先頭の 1 文字がそのまま出力されます。合致したものの出力コードの部分がモードの状態を変える関数 (on、off、switch など) である場合、使用される対応表がモード定義表の記述にしたがって変更されます。これらのモードを変える関数は、モードの状態 (on、off) に関係なく、絶えず使用される表に記述してください。また、機能の (restart) の入力コードの部分に合致した場合は、モード定義表そのものの再読み込みが行われます。ただし、そのモード定義表は前回と同じファイルです。この機能を使うことで、オートマトンの使用中に修正した変換表 (モード定義表を含む) を、オートマトンを終えずにその変換内容を変えることができます。
後処理では、1 つの入力コードに対して 1 つ以上の出力コードが最終出力として出力されます。出力コードが 1 つ以上出力されることを除いて前処理と同じです。
下記の例では、「Ls」または「LS」が入力されたとき「ls –la (改行)」が出力されます。