ようやくversio 0.9.0で実装を始めた音韻関連の機能が整いつつあります。直近で更新した内容は、韻文中での発音に関する二点です。
修正点 versio 0.9.5の詳細と、実装方法の紹介
versio 0.9.5 (23-a publikigo, en 2007/09/11)
- 【機能追加】韻文中の「’」で終わる語の発音(アクセントを含む)を正しく表示するようにしました。例えば、esper’をこれまで「エスペル」と読んでいましたが、正しく「エスペール」と読むようにしました。
- 【機能追加】「l’」の後に母音が続く場合に、発音を後続の語と融合するようにしました。例えば、韻文中でl’ esperoではなくl’esperoと続けて書いたとき前提ですが、「ルエスペーロ」ではなく「レスペーロ」と読むようにしました。
前者では、アクセントを変更しないという点が曲者です。エスペラントの規則性ゆえに、実装も極めて論理的かつ簡素なものとなっていたのですが、こういう特例の存在により、優雅さとは程遠い泥臭い実装を行う羽目になります。前者ではl’を「ル」と読めるようになるのですが、l’armoをルアーモと読んでしまうために、ここでも特例を設けてラーモと読めるように処理を書き加えました。
エスペラントの字面から発音を得るロジック
良い機会なので、発音をカタカナやIPAで転記する処理の概要をご紹介します。あまり変なことを考えず、人間の頭の中で行っている処理を素直にコード化することが一番と言えます。
- まず、これまでの形態素解析で、既に語根や接辞の区切り文字を持った文字列が得られています。例えば、samideanojnという単語はsam/ide/an/o/j/nという文法上の区切りです。
- ここで、単純に「/」を区切り文字として、splitにより元の文字列というスカラを一旦リストに分解して配列に突っ込みます。
- この配列について、接尾辞や品詞語尾であった場合には、前の要素と結合するようにします。例えば、
('sam', 'ide', 'an', 'o', 'j', 'n')は('sam', 'ideanojn')になります。これはまだ文法上の区切りですが、続け読みが出来るように配慮された配列になっています。 - それぞれの要素について、「子音」「母音」「子音と母音」という音韻上の区切りを得ます。この際、文字が母音か子音かを判断しながら、文字を一つずつ処理していきます。内部処理では字上符付き文字をx後置式としているので、ここが私がうっかりはまった陥穽でした。
'sam'は('sa', 'm')に、'ideanojn'は('i', 'de', 'a', 'no', 'j', 'n')に分解されます。これで、それぞれの要素が一つの音に対応するような配列になりました。 - 上記を結合して
('sa', 'm', 'i', 'de', 'a', 'n', 'o', 'j', 'n')というリストを得て、配列に突っ込みます。 - アクセント位置を決定します。配列を後ろから辿って、二つめの母音がある要素がアクセント付きの場所です。
- 上記状態を、単純にIPAに置換します。エスペラントのアルファベートはIPAと1対1の関係にありますから、単純に
trすれば事足ります。アクセント位置には長母音の記号を与えて完成です。samとideanojとの間は空白を入れておきます。 - また、カタカナ発音にも置換します。カタカナ発音は子音と母音からなる二重ハッシュ構造を予め作っておき、ハッシュのキーをそれぞれ指定すれば事足ります。例えば、
'sa'は$japana->{'s'}{'a'}で「サ」が求まりますし、母音のみや子音のみの場合にはダミーのキーを与えて$japana->{'m'}{'_'}で「ム」、$japana->{'_'}{'i}で「イ」が求まるという次第です。長母音で「ー」を与えて完成です。
このように可能な限り手を抜いて楽をして発音させている無邪気な実装なので、世知辛いesper’などという文字列を与えたら、まず「’」なんてハッシュキーがないのでこけますし、これを無視したら母音が一つ足りないわけでエスペル(エがアクセント)と読もうとするしで大変です。
そこで、以下のように機能追加することによって、こうした言語現象にも対応出来るようにしました。
母音省略への対応
いくら特例とはいえども、ここでも手を抜いて実装することがプログラマの美徳です。末尾が「’」の場合には、母音省略のフラグを立てておいて、単にoを語尾に補完すればよいのです。
ただし、それは上記3の処理の後にすることが大事です。そうでないと、せっかくesper’としたのにesperoと書いた場合と同じになってしまいます。さて、そうすると上記3の後で本来('espero')となるところが、('esper', 'o')という形のリストを得ることが出来ます。すると、4の後で('e', 's', 'pe', 'ro')となるべきところが('e', 's', 'pe', 'r', 'o')というリストを得られるので、発音は「エスペールオ」のようになります。後は単純に末尾をchopすれば「エスペール」という読みの完成です。
l’esperoの場合はこれは簡単で、単にl/esper/oという文字列を得てしまえば後は勝手にレスペーロと読んでくれます。
エスペラントの合理性に乾杯
このようにして最終的には韻文中の単語にも対応出来る発音解析機能が実装出来ましたが、いかにも付け焼き刃的な対応ではないかという感は否めません。作詞家が聞けばお気を悪くされるかも知れませんが、韻文等という使用頻度の低い言語現象に対して、費やしたコードの行数は一般的な言語現象と韻文との比率からは求まらない長さとなります。
流石に追加処理の方が既存処理よりも長くなることは有り得ませんが、エスペラント語に特例が多かったら、趣味のプログラミングではとても賄いきれなくなることは必至です。特例がない(ないしは極めて少ない)エスペラントの合理性や経済性に改めて舌を巻くばかりです。