Gaucheでも日本語を喋らせる(2)
「計算された未来」と言う事で、日蝕見物に大金をつぎ込んで南の島まで出かけた皆さん、 ご愁傷様でした。
私の所では、チラ見出来ました。道ゆく人が、携帯を空に向けているものだから、 私も空を仰いでみたら、見えた次第。
Googleのバナーも、日蝕モードに成っていたし、中国では、雲を吹き飛ばす大砲を 打ち上げるとか、得意の戦法で、お祭りでしたね。あと、eclipse方面の人達も、 日蝕記念バージョンとかを、出したのだろうか? 行ってみたけど それらしいのは、無かったよ。お祭り好きな人はいないのかな。
大体、何十年も先の事がぴたりと的中出来るのに、明日の天気さえ的中出来ない 現代科学技術の落差が、いとおかし。
ぴたり的中の基礎は、サロス周期に よるそうだ。明日の天気をぴたりと当てるには、蝶のはばたきまでも、考慮が必要。 だから、当たらないんです、と、ある予報官は弁明する。(かな?)
文字列の分解とひらがな化
今までは、KAKASIにその任をお願いしていたが、gauche業界での主流はmecab のようだ。時流に乗り遅れないように、mecabを使ってみる。
辞書込みのmecab-0.98pre3.exeを入れた。KAKASIと違って、辞書の在り処を設定する 必要も無いので、楽だ。(設定したのは、PATHだけ)
ちょっと試運転
c:\>mecab -O wakati test123.45hello test 123 . 45 hello 今日は、空を仰ぐ日です。 今日 は 、 空 を 仰ぐ 日 です 。 c:\>mecab -O yomi 今日は、空を見る日です。 キョウハ、ソラヲミルヒデス。 test123.45hello test123.45hello
wakatiとyomiを一遍でやってくれるのが欲しいんだ。マニュアル片手に嗜好錯誤。(なかなか、 素敵な変換するなあ)
c:\>mecab --eos-format=\n --unk-format=%m\s --node-format=%pS%f[7]\s 今日は、空を仰ぐ日です。 キョウ ハ 、 ソラ ヲ アオグ ヒ デス 。 test12.345hello test 12 . 345 hello
ちゃんとパースされて、後の処理が楽に行きそうな形になったな。
gaucheから、呼んでみる
上記を、gaucheから、呼びたい。変換前のデータを、mecabに渡し、結果をgauche界に 返してもらう事を考慮すると、使える手続きは限られてくる。また、文字コード 変換や、返り値をListにしたいと言う要望もある。
(use gauche.process) (use gauche.charconv) (define (trans str) (call-with-process-io '("mecab" "--eos-format=\n" "--unk-format=%m\s" "--node-format=%pS%f[7]\s" ) (lambda (in out) (display (ces-convert str 'utf-8 'sjis) out) (newline out) (flush out) (close-output-port out) (string-split (ces-convert (read-line in #t) 'sjis) " ")))) (trans "abc123def")
実験してみると、結果が返ってこない。同じコードをFreeBSDで実行すると、ちゃんと 分解されて、Listになって返ってくる。
待っている時に、Ctrl-Cで停止させると
*** UNHANDLED-SIGNAL-ERROR: unhandled signal 2 (SIGINT) Stack Trace: _______________________________________ 0 (sys-waitpid (process-pid process) :nohang nohang?) At line 235 of "c:\\app\\Gauche\\share\\gauche\\0.8.14\\lib/gauche/process.scm" 1 (process-wait p) At line 337 of "c:\\app\\Gauche\\share\\gauche\\0.8.14\\lib/gauche/process.scm" 2 h
どうやら、終了待ちのようだ。タスクマネージャで確認したら、mecabは起動してたけど 詳細なデータは取れないのかな? メニューを突付いてみたら、表示列で選べるようだ。
- 読み取り 66
- 読み取りバイト数 57326
- 書き込み 24
- 書き込みバイト数 91424
都合よく、PIPEへの、出入りを表示してくれるオプションは、勿論(M$の事だから) 有る訳は無い。それに、何処への出入りかも不明。DISKへか?メモリーへか? ちゃんと したマニュアルは有るのかな?
(define (call-with-process-io command proc :key ((:error err) #f) (host #f) (on-abnormal-exit :error) :allow-other-keys rest) (let* ((p (%apply-run-process command :pipe :pipe err host)) (i (wrap-input-process-port p rest)) (o (wrap-output-process-port p rest))) (unwind-protect (proc i o) (begin (close-output-port o) (close-input-port i) (process-wait p) (handle-abnormal-exit on-abnormal-exit p)))))
上記は、問題?の部分だけど、見えるって、いいなあ。勉強になります。 データ(終わりマークも含めて)が行かないので、ずっと待ってて、止まってる ように、gauche界からは観測される?
あれ? 終わりマークは、"\r\n" でも、"\n" でも、どちらでもいいのかな? いつも、良きに計らってもらっているから、気にした事無かったなあ。
shiroさんに相談
話は前後するけど、しゃとん経由で shiroさん、齋藤さんに相談してみた。上記は、以前、'(mecab ...)の部分を "mecab ..." としていて、醜いエラーを食らっていたのだ。
shiroさんからは、何点か調査依頼があり、PIPEの受け渡しがうまくいくかを検証した。
元になる、input.txtは、"abc123def\n"
(use gauche.process) (let1 p (run-process '("mecab" "-O" "wakati") :input "input.txt" :output :pipe) (read-line (process-output p) #t))
出力は、"abc 123 def " と、返ってきた。(報告、間違ってました。すみません)
(use gauche.process) (let1 p (run-process '("mecab" "-O" "wakati") :input :pipe :output "output.txt") (display "abc123def\n" (process-input p)) (close-output-port (process-input p)))
こちらは、output.txt に、"abc 123 def \n" と、残っていた。
input, output の両方を PIPEにした、call-with-process-io は、read-lineで ブロックされてしまう、謎が残る結果でした。
使った環境は
- WindowsXP SP3
- GLUTを動かす時に使わせて頂いた http://saito.s4.xrea.com/?Gauche
でも、相談したおかげで、わけわかめな、command.com を避ける方法を教えて 頂けたし、これで、取りあえず先に進みます。
PS. しゃとんで、複数行を入力するのって、どうやるのでしょうか? Returnキーを叩くと、投稿されちゃうので、 今までは、 editorで書いておいてから、それを貼り付けてました。それが、見え々になって、ちょっと カッコ悪いです。