ローマ字入力の文字をひらがなの文字に変換してみました。
まだ異常入力への対応やら小文字への変換やら濁音拗音促音などの対応とかはしてませんけど
基礎的な変換はできてます。
(defparameter *boin-table* '(("a" . "あ") ("i" . "い") ("u" . "う") ("e" . "え") ("o" . "お"))) (defun create-kana-row (prefix-str kanas) (loop for boin in *boin-table* for kana in kanas collect (cons (concatenate 'string prefix-str (car boin)) kana))) (defparameter *hiragana-table* `(,@*boin-table* ,@(create-kana-row "k" '("か" "き" "く" "け" "こ")) ,@(create-kana-row "s" '("さ" "し" "す" "せ" "そ")) ,@(create-kana-row "t" '("た" "ち" "つ" "て" "と")) ,@(create-kana-row "n" '("な" "に" "ぬ" "ね" "の")) ,@(create-kana-row "h" '("は" "ひ" "ふ" "へ" "ほ")) ,@(create-kana-row "m" '("ま" "み" "む" "め" "も")) ("ya" . "や") ("yu" . "ゆ") ("yo" . "よ") ,@(create-kana-row "r" '("ら" "り" "る" "れ" "ろ")) ("wa" . "わ") ("wo" . "を") ("nn" . "ん"))) (defun translate-roman-to-hiragana (roman-str) (labels ((%translate-roman-to-hiragana (carry-char acc char-list) (cond ((null char-list) (apply #'concatenate 'string (nreverse acc))) (#1=(assoc (coerce `(,@(if carry-char (list carry-char) nil) ,(car char-list)) 'string) *hiragana-table* :test #'string=) (%translate-roman-to-hiragana nil (cons (cdr #1#) acc) (cdr char-list))) (t (%translate-roman-to-hiragana (car char-list) acc (cdr char-list)))))) (%translate-roman-to-hiragana nil '() (coerce roman-str 'list))))
まずは、ka=>か 等の変換テーブルをつくっておきます。
変換は
1. 文字がもうなかったら、結果を文字列にして返す
2. 繰りこしてある文字と、今の先頭の文字を接合して、変換テーブルを検索、みつかれば3へそうでなければ4
3. みつかった文字を保存して、繰りこし文字を消去して2へもどる
4. 先頭の一文字を繰りこして、2へもどる
とやっています。
最初は子音の変換のモードかどうかとかを判定しようかなとか考えたのですが、
冗長だなぁとおもい、また今は小文字などの3文字以上の入力を見ることも考えていないので
一つ前の文字さえ確認できれば十分だなぁという事で、このようにしています。
CL-USER(62): (translate-roman-to-hiragana "konnnitiwa") "こんにちわ"