リポジトリ / emssr / independent_common_compiler
r2
| r2 emssr | 1 | # -*- coding: utf-8 -*- |
| r2 emssr | 2 | """音節と生成元の対応表。 |
| r2 emssr | 3 | |
| r2 emssr | 4 | doc: plain.format commonc.generators casm.generators |
| r2 emssr | 5 | |
| r2 emssr | 6 | 音節番号は生成順で決まる(19 式 2.1)。 |
| r2 emssr | 7 | |
| r2 emssr | 8 | idx(cv) = 5 ord(c) + ord(v) |
| r2 emssr | 9 | C = (k s t n h m y r w g z d b p), V = (a i u e o) |
| r2 emssr | 10 | |
| r2 emssr | 11 | commonc の SYL 配列(19 §3.2)はこの番号をそのまま並べる。表はそこから引く。 |
| r2 emssr | 12 | |
| r2 emssr | 13 | 範囲は三つに分かれる。 |
| r2 emssr | 14 | |
| r2 emssr | 15 | idx <= 59 一音節の生成元 |
| r2 emssr | 16 | idx 60..69 見出しの字母 Σ_V = {be bo pa pi pu pe po}(06 §17) |
| r2 emssr | 17 | ku + 二音節 三音節の生成元。領域の語(region.cam) |
| r2 emssr | 18 | |
| r2 emssr | 19 | pin と pout は境界語を一段動かす幅(13 式 1.2)。boxes は Desc が開く MBox の本数 |
| r2 emssr | 20 | (16 §5)で、0 の語は実行費用を持たない。 |
| r2 emssr | 21 | """ |
| r2 emssr | 22 | |
| r2 emssr | 23 | CONSONANT = "kstnhmyrwgzdbp" |
| r2 emssr | 24 | VOWEL = "aiueo" |
| r2 emssr | 25 | |
| r2 emssr | 26 | |
| r2 emssr | 27 | def name(idx): |
| r2 emssr | 28 | """音節番号から綴りを返す""" |
| r2 emssr | 29 | return CONSONANT[idx // 5] + VOWEL[idx % 5] |
| r2 emssr | 30 | |
| r2 emssr | 31 | |
| r2 emssr | 32 | def index(syl): |
| r2 emssr | 33 | """綴りから音節番号を返す""" |
| r2 emssr | 34 | return 5 * CONSONANT.index(syl[0]) + VOWEL.index(syl[1]) |
| r2 emssr | 35 | |
| r2 emssr | 36 | |
| r2 emssr | 37 | # 欄は (記号, pin, pout, 開く箱の本数, 層) になる。 |
| r2 emssr | 38 | # |
| r2 emssr | 39 | # 層は画面の色分けにだけ使う。 |
| r2 emssr | 40 | # frame 文の区切り。層境界と無声ワイヤ |
| r2 emssr | 41 | # dyad 二進有理数 Z[1/2] の上の演算 |
| r2 emssr | 42 | # bit 二値 |
| r2 emssr | 43 | # store 作業領域 |
| r2 emssr | 44 | # omega 閉包 Ω_a |
| r2 emssr | 45 | # judge 判定値 Q。非可換 quantale(GCLS 定理 3.3) |
| r2 emssr | 46 | # region 幾何の領域と鎖 |
| r2 emssr | 47 | # report 報告 |
| r2 emssr | 48 | # letter 見出しの字母 |
| r2 emssr | 49 | ATOM = { |
| r2 emssr | 50 | "ka": ("層境界", 0, 0, 0, "frame"), |
| r2 emssr | 51 | "ki": ("id", 1, 1, 0, "frame"), |
| r2 emssr | 52 | "ku": ("零標示 z_e", 0, 0, 0, "frame"), |
| r2 emssr | 53 | |
| r2 emssr | 54 | "hu": ("one", 0, 1, 1, "dyad"), |
| r2 emssr | 55 | "no": ("⊕", 2, 1, 1, "dyad"), |
| r2 emssr | 56 | "ha": ("⊖", 1, 1, 1, "dyad"), |
| r2 emssr | 57 | "ti": ("⋆", 2, 1, 1, "dyad"), |
| r2 emssr | 58 | "se": ("β", 1, 1, 4, "dyad"), |
| r2 emssr | 59 | "he": ("Δ", 1, 2, 0, "dyad"), |
| r2 emssr | 60 | "ho": ("!", 1, 0, 0, "dyad"), |
| r2 emssr | 61 | |
| r2 emssr | 62 | "so": ("φ∂", 1, 1, 8, "bit"), |
| r2 emssr | 63 | "hi": ("≤", 2, 1, 8, "bit"), |
| r2 emssr | 64 | "mo": ("π", 1, 1, 0, "bit"), |
| r2 emssr | 65 | |
| r2 emssr | 66 | "mi": ("Load", 1, 1, 1, "store"), |
| r2 emssr | 67 | "mu": ("Store", 2, 0, 1, "store"), |
| r2 emssr | 68 | |
| r2 emssr | 69 | "ya": ("Ω 開き", 0, 0, 0, "omega"), |
| r2 emssr | 70 | "yi": ("Ω 閉じ", 1, 0, 1, "omega"), |
| r2 emssr | 71 | |
| r2 emssr | 72 | "to": ("整合対", 2, 1, None, "judge"), |
| r2 emssr | 73 | "na": ("原型 1 と整合", 1, 1, None, "judge"), |
| r2 emssr | 74 | "ni": ("原型 0 と整合", 1, 1, None, "judge"), |
| r2 emssr | 75 | "nu": ("⋆_Q", 2, 1, None, "judge"), |
| r2 emssr | 76 | "ne": ("所属", 1, 1, None, "judge"), |
| r2 emssr | 77 | "yu": ("⋁", 2, 1, None, "judge"), |
| r2 emssr | 78 | "ye": ("↘", 2, 1, None, "judge"), |
| r2 emssr | 79 | "yo": ("↙", 2, 1, None, "judge"), |
| r2 emssr | 80 | "ra": ("≤_Q", 2, 1, None, "judge"), |
| r2 emssr | 81 | "ri": ("hom", 2, 1, None, "judge"), |
| r2 emssr | 82 | "ru": ("π_Q", 1, 1, None, "judge"), |
| r2 emssr | 83 | "go": ("Θ", 1, 1, None, "judge"), |
| r2 emssr | 84 | |
| r2 emssr | 85 | "bi": ("∂", 1, 1, 0, "region"), |
| r2 emssr | 86 | "bu": ("⊕ 鎖", 2, 1, 0, "region"), |
| r2 emssr | 87 | |
| r2 emssr | 88 | # ツイ数平面。型名 T/P/R はそれぞれ複数の lane64 語で表す。 |
| r2 emssr | 89 | # Trace T = 4 語 |
| r2 emssr | 90 | # Point P = 2 語 |
| r2 emssr | 91 | # Reflection R = 1 語 |
| r2 emssr | 92 | # pin/pout は抽象オブジェクトの個数ではなく、この境界語の本数になる。 |
| r2 emssr | 93 | # 箱数は commonc の正規化で生成元単位に固定できないため None とする。 |
| r2 emssr | 94 | "re": ("trace", 0, 4, None, "plane"), |
| r2 emssr | 95 | "sa": ("i", 4, 4, None, "plane"), |
| r2 emssr | 96 | "si": ("j", 4, 4, None, "plane"), |
| r2 emssr | 97 | "ke": ("id", 4, 4, None, "plane"), |
| r2 emssr | 98 | "su": ("⊖ trace", 4, 4, None, "plane"), |
| r2 emssr | 99 | "ro": ("ρ⁻", 4, 4, None, "plane"), |
| r2 emssr | 100 | "wa": ("ρ⁺", 4, 4, None, "plane"), |
| r2 emssr | 101 | "wi": ("endpoint", 4, 2, None, "plane"), |
| r2 emssr | 102 | "ko": ("id coord", 2, 2, None, "plane"), |
| r2 emssr | 103 | "ta": ("⊕ coord", 4, 2, None, "plane"), |
| r2 emssr | 104 | "de": ("実成分", 2, 2, None, "plane"), |
| r2 emssr | 105 | "do": ("無限成分", 2, 2, None, "plane"), |
| r2 emssr | 106 | "wu": ("E", 0, 1, None, "plane"), |
| r2 emssr | 107 | "we": ("R_r", 0, 1, None, "plane"), |
| r2 emssr | 108 | "wo": ("R_ij", 0, 1, None, "plane"), |
| r2 emssr | 109 | "ga": ("合成", 2, 1, None, "plane"), |
| r2 emssr | 110 | "gi": ("act", 3, 2, None, "plane"), |
| r2 emssr | 111 | |
| r2 emssr | 112 | "me": ("Ok", 0, 0, 1, "report"), |
| r2 emssr | 113 | "di": ("Ko", 0, 0, 1, "report"), |
| r2 emssr | 114 | "du": ("Put", 1, 0, 1, "report"), |
| r2 emssr | 115 | } |
| r2 emssr | 116 | |
| r2 emssr | 117 | # ku を頭に置く三音節の生成元(region.cam) |
| r2 emssr | 118 | TRIPLE = { |
| r2 emssr | 119 | "kukeke": ("領域", 1, 1, 0, "region"), |
| r2 emssr | 120 | "kukeko": ("共通部", 2, 1, 0, "region"), |
| r2 emssr | 121 | "kukesa": ("合わせ", 2, 1, 0, "region"), |
| r2 emssr | 122 | "kukesi": ("外側", 2, 1, 0, "region"), |
| r2 emssr | 123 | "kukesu": ("境界 ∂", 1, 1, 0, "region"), |
| r2 emssr | 124 | "kukese": ("含まれる", 2, 1, 1, "region"), |
| r2 emssr | 125 | "kukeso": ("重なり", 2, 1, 1, "region"), |
| r2 emssr | 126 | "kuketa": ("隣接", 2, 1, 1, "region"), |
| r2 emssr | 127 | "kuketi": ("道", 1, 1, 1, "region"), |
| r2 emssr | 128 | } |
| r2 emssr | 129 | |
| r2 emssr | 130 | # 見出しの字母(06 §17)。採用語彙の名前だけに使い、生成元ではない |
| r2 emssr | 131 | LETTERS = ("be", "bo", "pa", "pi", "pu", "pe", "po") |
| r2 emssr | 132 | |
| r2 emssr | 133 | LAYER_BOUNDARY = 0 # ka |
| r2 emssr | 134 | IDENTITY = 1 # ki |
| r2 emssr | 135 | ZERO_MARK = 2 # ku |
| r2 emssr | 136 | |
| r2 emssr | 137 | |
| r2 emssr | 138 | def stream(text): |
| r2 emssr | 139 | """filter_Σ(16 §1.1、19 式 4.1)。音節表の外の字を落として番号の列にする。 |
| r2 emssr | 140 | |
| r2 emssr | 141 | ASCII 小文字が音節へ切れない所は誤りになる。 |
| r2 emssr | 142 | """ |
| r2 emssr | 143 | keep = [c for c in text if "a" <= c <= "z"] |
| r2 emssr | 144 | if len(keep) % 2: |
| r2 emssr | 145 | raise ValueError("音節の途中で切れている: ...%s" % "".join(keep[-5:])) |
| r2 emssr | 146 | out = [] |
| r2 emssr | 147 | for k in range(0, len(keep), 2): |
| r2 emssr | 148 | c, v = keep[k], keep[k + 1] |
| r2 emssr | 149 | if c not in CONSONANT or v not in VOWEL: |
| r2 emssr | 150 | raise ValueError("音節表に無い綴り: %s%s" % (c, v)) |
| r2 emssr | 151 | out.append(5 * CONSONANT.index(c) + VOWEL.index(v)) |
| r2 emssr | 152 | return out |
| r2 emssr | 153 | |
| r2 emssr | 154 | |
| r2 emssr | 155 | def look(spelling): |
| r2 emssr | 156 | """綴りから (記号, pin, pout, 箱, 層) を返す。表に無い綴りは None""" |
| r2 emssr | 157 | return TRIPLE.get(spelling) or ATOM.get(spelling) |
| r2 emssr | 158 | |
| r2 emssr | 159 | |
| r2 emssr | 160 | def read(syl, lexicon=None): |
| r2 emssr | 161 | """SYL の番号列を語へ切る。返りは (綴り, 記号, pin, pout, 箱, 層, 長さ)。 |
| r2 emssr | 162 | |
| r2 emssr | 163 | ku で始まる三音節は一語にまとめる。見出しの字母が続く区間も一語にまとめる |
| r2 emssr | 164 | ので、採用語彙の見出しがそのまま画面に出る。 |
| r2 emssr | 165 | |
| r2 emssr | 166 | lexicon は {見出し: (pin, pout, 箱)}。見出しは文を差し込む(16 式 1.6)ので、 |
| r2 emssr | 167 | 境界の幅は差し込む文が決める。渡さないと幅 0 として置く。 |
| r2 emssr | 168 | """ |
| r2 emssr | 169 | lexicon = lexicon or {} |
| r2 emssr | 170 | out = [] |
| r2 emssr | 171 | i = 0 |
| r2 emssr | 172 | n = len(syl) |
| r2 emssr | 173 | while i < n: |
| r2 emssr | 174 | s = name(syl[i]) |
| r2 emssr | 175 | if s == "ku" and i + 2 < n: |
| r2 emssr | 176 | t = s + name(syl[i + 1]) + name(syl[i + 2]) |
| r2 emssr | 177 | hit = TRIPLE.get(t) |
| r2 emssr | 178 | if hit: |
| r2 emssr | 179 | out.append((t,) + hit + (3,)) |
| r2 emssr | 180 | i += 3 |
| r2 emssr | 181 | continue |
| r2 emssr | 182 | if s in LETTERS: |
| r2 emssr | 183 | j = i |
| r2 emssr | 184 | word = "" |
| r2 emssr | 185 | while j < n and name(syl[j]) in LETTERS: |
| r2 emssr | 186 | word += name(syl[j]) |
| r2 emssr | 187 | j += 1 |
| r2 emssr | 188 | pin, pout, bx = lexicon.get(word, (0, 0, None)) |
| r2 emssr | 189 | out.append((word, "見出し", pin, pout, bx, "letter", j - i)) |
| r2 emssr | 190 | i = j |
| r2 emssr | 191 | continue |
| r2 emssr | 192 | hit = ATOM.get(s) |
| r2 emssr | 193 | if hit: |
| r2 emssr | 194 | out.append((s,) + hit + (1,)) |
| r2 emssr | 195 | else: |
| r2 emssr | 196 | out.append((s, "未登録", 0, 0, None, "unknown", 1)) |
| r2 emssr | 197 | i += 1 |
| r2 emssr | 198 | return out |