📦 Out of Context リポジトリ

リポジトリ / emssr / independent_common_compiler

r2
r2 emssr1
# -*- coding: utf-8 -*-
r2 emssr2
"""音節と生成元の対応表。
r2 emssr3
r2 emssr4
doc: plain.format commonc.generators casm.generators
r2 emssr5
r2 emssr6
音節番号は生成順で決まる(19 式 2.1)。
r2 emssr7
r2 emssr8
    idx(cv) = 5 ord(c) + ord(v)
r2 emssr9
    C = (k s t n h m y r w g z d b p),  V = (a i u e o)
r2 emssr10
r2 emssr11
commonc の SYL 配列(19 §3.2)はこの番号をそのまま並べる。表はそこから引く。
r2 emssr12
r2 emssr13
範囲は三つに分かれる。
r2 emssr14
r2 emssr15
    idx <= 59      一音節の生成元
r2 emssr16
    idx 60..69     見出しの字母 Σ_V = {be bo pa pi pu pe po}(06 §17)
r2 emssr17
    ku + 二音節    三音節の生成元。領域の語(region.cam)
r2 emssr18
r2 emssr19
pin と pout は境界語を一段動かす幅(13 式 1.2)。boxes は Desc が開く MBox の本数
r2 emssr20
(16 §5)で、0 の語は実行費用を持たない。
r2 emssr21
"""
r2 emssr22
r2 emssr23
CONSONANT = "kstnhmyrwgzdbp"
r2 emssr24
VOWEL = "aiueo"
r2 emssr25
r2 emssr26
r2 emssr27
def name(idx):
r2 emssr28
    """音節番号から綴りを返す"""
r2 emssr29
    return CONSONANT[idx // 5] + VOWEL[idx % 5]
r2 emssr30
r2 emssr31
r2 emssr32
def index(syl):
r2 emssr33
    """綴りから音節番号を返す"""
r2 emssr34
    return 5 * CONSONANT.index(syl[0]) + VOWEL.index(syl[1])
r2 emssr35
r2 emssr36
r2 emssr37
# 欄は (記号, pin, pout, 開く箱の本数, 層) になる。
r2 emssr38
#
r2 emssr39
# 層は画面の色分けにだけ使う。
r2 emssr40
#   frame   文の区切り。層境界と無声ワイヤ
r2 emssr41
#   dyad    二進有理数 Z[1/2] の上の演算
r2 emssr42
#   bit     二値
r2 emssr43
#   store   作業領域
r2 emssr44
#   omega   閉包 Ω_a
r2 emssr45
#   judge   判定値 Q。非可換 quantale(GCLS 定理 3.3)
r2 emssr46
#   region  幾何の領域と鎖
r2 emssr47
#   report  報告
r2 emssr48
#   letter  見出しの字母
r2 emssr49
ATOM = {
r2 emssr50
    "ka": ("層境界", 0, 0, 0, "frame"),
r2 emssr51
    "ki": ("id", 1, 1, 0, "frame"),
r2 emssr52
    "ku": ("零標示 z_e", 0, 0, 0, "frame"),
r2 emssr53
r2 emssr54
    "hu": ("one", 0, 1, 1, "dyad"),
r2 emssr55
    "no": ("⊕", 2, 1, 1, "dyad"),
r2 emssr56
    "ha": ("⊖", 1, 1, 1, "dyad"),
r2 emssr57
    "ti": ("⋆", 2, 1, 1, "dyad"),
r2 emssr58
    "se": ("β", 1, 1, 4, "dyad"),
r2 emssr59
    "he": ("Δ", 1, 2, 0, "dyad"),
r2 emssr60
    "ho": ("!", 1, 0, 0, "dyad"),
r2 emssr61
r2 emssr62
    "so": ("φ∂", 1, 1, 8, "bit"),
r2 emssr63
    "hi": ("≤", 2, 1, 8, "bit"),
r2 emssr64
    "mo": ("π", 1, 1, 0, "bit"),
r2 emssr65
r2 emssr66
    "mi": ("Load", 1, 1, 1, "store"),
r2 emssr67
    "mu": ("Store", 2, 0, 1, "store"),
r2 emssr68
r2 emssr69
    "ya": ("Ω 開き", 0, 0, 0, "omega"),
r2 emssr70
    "yi": ("Ω 閉じ", 1, 0, 1, "omega"),
r2 emssr71
r2 emssr72
    "to": ("整合対", 2, 1, None, "judge"),
r2 emssr73
    "na": ("原型 1 と整合", 1, 1, None, "judge"),
r2 emssr74
    "ni": ("原型 0 と整合", 1, 1, None, "judge"),
r2 emssr75
    "nu": ("⋆_Q", 2, 1, None, "judge"),
r2 emssr76
    "ne": ("所属", 1, 1, None, "judge"),
r2 emssr77
    "yu": ("⋁", 2, 1, None, "judge"),
r2 emssr78
    "ye": ("↘", 2, 1, None, "judge"),
r2 emssr79
    "yo": ("↙", 2, 1, None, "judge"),
r2 emssr80
    "ra": ("≤_Q", 2, 1, None, "judge"),
r2 emssr81
    "ri": ("hom", 2, 1, None, "judge"),
r2 emssr82
    "ru": ("π_Q", 1, 1, None, "judge"),
r2 emssr83
    "go": ("Θ", 1, 1, None, "judge"),
r2 emssr84
r2 emssr85
    "bi": ("∂", 1, 1, 0, "region"),
r2 emssr86
    "bu": ("⊕ 鎖", 2, 1, 0, "region"),
r2 emssr87
r2 emssr88
    # ツイ数平面。型名 T/P/R はそれぞれ複数の lane64 語で表す。
r2 emssr89
    #   Trace T      = 4 語
r2 emssr90
    #   Point P      = 2 語
r2 emssr91
    #   Reflection R = 1 語
r2 emssr92
    # pin/pout は抽象オブジェクトの個数ではなく、この境界語の本数になる。
r2 emssr93
    # 箱数は commonc の正規化で生成元単位に固定できないため None とする。
r2 emssr94
    "re": ("trace", 0, 4, None, "plane"),
r2 emssr95
    "sa": ("i", 4, 4, None, "plane"),
r2 emssr96
    "si": ("j", 4, 4, None, "plane"),
r2 emssr97
    "ke": ("id", 4, 4, None, "plane"),
r2 emssr98
    "su": ("⊖ trace", 4, 4, None, "plane"),
r2 emssr99
    "ro": ("ρ⁻", 4, 4, None, "plane"),
r2 emssr100
    "wa": ("ρ⁺", 4, 4, None, "plane"),
r2 emssr101
    "wi": ("endpoint", 4, 2, None, "plane"),
r2 emssr102
    "ko": ("id coord", 2, 2, None, "plane"),
r2 emssr103
    "ta": ("⊕ coord", 4, 2, None, "plane"),
r2 emssr104
    "de": ("実成分", 2, 2, None, "plane"),
r2 emssr105
    "do": ("無限成分", 2, 2, None, "plane"),
r2 emssr106
    "wu": ("E", 0, 1, None, "plane"),
r2 emssr107
    "we": ("R_r", 0, 1, None, "plane"),
r2 emssr108
    "wo": ("R_ij", 0, 1, None, "plane"),
r2 emssr109
    "ga": ("合成", 2, 1, None, "plane"),
r2 emssr110
    "gi": ("act", 3, 2, None, "plane"),
r2 emssr111
r2 emssr112
    "me": ("Ok", 0, 0, 1, "report"),
r2 emssr113
    "di": ("Ko", 0, 0, 1, "report"),
r2 emssr114
    "du": ("Put", 1, 0, 1, "report"),
r2 emssr115
}
r2 emssr116
r2 emssr117
# ku を頭に置く三音節の生成元(region.cam)
r2 emssr118
TRIPLE = {
r2 emssr119
    "kukeke": ("領域", 1, 1, 0, "region"),
r2 emssr120
    "kukeko": ("共通部", 2, 1, 0, "region"),
r2 emssr121
    "kukesa": ("合わせ", 2, 1, 0, "region"),
r2 emssr122
    "kukesi": ("外側", 2, 1, 0, "region"),
r2 emssr123
    "kukesu": ("境界 ∂", 1, 1, 0, "region"),
r2 emssr124
    "kukese": ("含まれる", 2, 1, 1, "region"),
r2 emssr125
    "kukeso": ("重なり", 2, 1, 1, "region"),
r2 emssr126
    "kuketa": ("隣接", 2, 1, 1, "region"),
r2 emssr127
    "kuketi": ("道", 1, 1, 1, "region"),
r2 emssr128
}
r2 emssr129
r2 emssr130
# 見出しの字母(06 §17)。採用語彙の名前だけに使い、生成元ではない
r2 emssr131
LETTERS = ("be", "bo", "pa", "pi", "pu", "pe", "po")
r2 emssr132
r2 emssr133
LAYER_BOUNDARY = 0          # ka
r2 emssr134
IDENTITY = 1                # ki
r2 emssr135
ZERO_MARK = 2               # ku
r2 emssr136
r2 emssr137
r2 emssr138
def stream(text):
r2 emssr139
    """filter_Σ(16 §1.1、19 式 4.1)。音節表の外の字を落として番号の列にする。
r2 emssr140
r2 emssr141
    ASCII 小文字が音節へ切れない所は誤りになる。
r2 emssr142
    """
r2 emssr143
    keep = [c for c in text if "a" <= c <= "z"]
r2 emssr144
    if len(keep) % 2:
r2 emssr145
        raise ValueError("音節の途中で切れている: ...%s" % "".join(keep[-5:]))
r2 emssr146
    out = []
r2 emssr147
    for k in range(0, len(keep), 2):
r2 emssr148
        c, v = keep[k], keep[k + 1]
r2 emssr149
        if c not in CONSONANT or v not in VOWEL:
r2 emssr150
            raise ValueError("音節表に無い綴り: %s%s" % (c, v))
r2 emssr151
        out.append(5 * CONSONANT.index(c) + VOWEL.index(v))
r2 emssr152
    return out
r2 emssr153
r2 emssr154
r2 emssr155
def look(spelling):
r2 emssr156
    """綴りから (記号, pin, pout, 箱, 層) を返す。表に無い綴りは None"""
r2 emssr157
    return TRIPLE.get(spelling) or ATOM.get(spelling)
r2 emssr158
r2 emssr159
r2 emssr160
def read(syl, lexicon=None):
r2 emssr161
    """SYL の番号列を語へ切る。返りは (綴り, 記号, pin, pout, 箱, 層, 長さ)。
r2 emssr162
r2 emssr163
    ku で始まる三音節は一語にまとめる。見出しの字母が続く区間も一語にまとめる
r2 emssr164
    ので、採用語彙の見出しがそのまま画面に出る。
r2 emssr165
r2 emssr166
    lexicon は {見出し: (pin, pout, 箱)}。見出しは文を差し込む(16 式 1.6)ので、
r2 emssr167
    境界の幅は差し込む文が決める。渡さないと幅 0 として置く。
r2 emssr168
    """
r2 emssr169
    lexicon = lexicon or {}
r2 emssr170
    out = []
r2 emssr171
    i = 0
r2 emssr172
    n = len(syl)
r2 emssr173
    while i < n:
r2 emssr174
        s = name(syl[i])
r2 emssr175
        if s == "ku" and i + 2 < n:
r2 emssr176
            t = s + name(syl[i + 1]) + name(syl[i + 2])
r2 emssr177
            hit = TRIPLE.get(t)
r2 emssr178
            if hit:
r2 emssr179
                out.append((t,) + hit + (3,))
r2 emssr180
                i += 3
r2 emssr181
                continue
r2 emssr182
        if s in LETTERS:
r2 emssr183
            j = i
r2 emssr184
            word = ""
r2 emssr185
            while j < n and name(syl[j]) in LETTERS:
r2 emssr186
                word += name(syl[j])
r2 emssr187
                j += 1
r2 emssr188
            pin, pout, bx = lexicon.get(word, (0, 0, None))
r2 emssr189
            out.append((word, "見出し", pin, pout, bx, "letter", j - i))
r2 emssr190
            i = j
r2 emssr191
            continue
r2 emssr192
        hit = ATOM.get(s)
r2 emssr193
        if hit:
r2 emssr194
            out.append((s,) + hit + (1,))
r2 emssr195
        else:
r2 emssr196
            out.append((s, "未登録", 0, 0, None, "unknown", 1))
r2 emssr197
        i += 1
r2 emssr198
    return out