import os import re import pandas as pd
def compiler_voynich_full_decompilation(): print("全域デコンパイラ 起動...\n")
# 入出力パスの設定
voynich_raw_txt = r"C:\Users\141798\Desktop\Voynich_Base\voynich.txt"
anchors_csv = r"C:\Users\141798\Desktop\Voynich_Base\Voynich_Absolute_Anchors_Phase5_128D.csv"
output_txt = r"C:\Users\141798\Desktop\Voynich_Base\Voynich_Decompiled_Record.txt"

if not os.path.exists(voynich_raw_txt) or not os.path.exists(anchors_csv):
    print("!!! 致命的エラー: 必要ファイル(手稿データまたはマスター辞書)が見つかりません。")
    return

# =====================================================================
# Phase 1: マスター辞書の無機質ロード
# =====================================================================
print("■ Phase 1: マスター辞書のロード (keep_default_na=False)")
# 【絶対防御】Pandasの勝手な意味解釈をパージしてロード
df_anchors = pd.read_csv(anchors_csv, keep_default_na=False)

# Target_Symbol -> Keyword のマッピング構築
# ※カラム名は Phase 5 出力仕様 (Target_Symbol, Keyword) に準拠
master_dict = dict(zip(df_anchors['Target_Symbol'].astype(str),
                       df_anchors['Keyword'].astype(str)))

print(f" -> マスター辞書に {len(master_dict)} 件の絶対アンカーを定着しました。\n")

# =====================================================================
# Phase 2: 全域デコンパイル（機械的一括置換）
# =====================================================================
print("■ Phase 2: 全域デコンパイル (物理レジスタ・マッピング)")

decompiled_lines = []
stats = {'total_words': 0, 'hits': 0, 'undefined': 0}

with open(voynich_raw_txt, "r", encoding="utf-8", errors="ignore") as f:
    for line in f:
        # 1. 位置メタデータ（<...>）を保護しつつ、それ以外を単語分割
        # メタデータ部分はそのまま残し、単語部分だけを置換対象にする
        metadata_match = re.match(r'(<[^>]+>)(.*)', line)
       
        if metadata_match:
            metadata = metadata_match.group(1)
            content = metadata_match.group(2)
        else:
            metadata = ""
            content = line

        # 2. 単語のパース (ピリオド, カンマ, ハイフン等を区切りとして認識)
        # ※前段のパース修復コンパイラ v5 と同一のデリミタ規則を適用
        words_in_line = re.split(r'([.,\-=\s]+)', content)
       
        processed_line_parts = []
        for part in words_in_line:
            # 区切り文字そのものではなく、単語（EVA記号）である場合
            if re.match(r'[^\s.,\-=]+', part):
                stats['total_words'] += 1
                eva_symbol = part.strip()
               
                if eva_symbol in master_dict:
                    # 既知アンカー：ラテン語へ置換
                    processed_line_parts.append(master_dict[eva_symbol])
                    stats['hits'] += 1
                else:
                    # 未知変数：冷酷にロック
                    processed_line_parts.append(f"[{eva_symbol}]")
                    stats['undefined'] += 1
            else:
                # 区切り文字や空白はそのまま保持
                processed_line_parts.append(part)
       
        decompiled_lines.append(f"{metadata}{''.join(processed_line_parts)}")

# =====================================================================
# Phase 3: 最終レコード・ダンプの出力
# =====================================================================
print("■ Phase 3: 最終レコード・ダンプの出力")
with open(output_txt, "w", encoding="utf-8") as f:
    f.writelines(decompiled_lines)

print("\n" + "="*80)
print("👑 【デコンパイル・サマリー】")
print(f" -> 総処理単語数: {stats['total_words']} words")
print(f" -> 置換成功数 (既知): {stats['hits']} hits")
print(f" -> 未定義変数の数: {stats['undefined']} slots")

hit_rate = (stats['hits'] / stats['total_words'] * 100) if stats['total_words'] > 0 else 0
print(f" -> 現時点での現像率: {hit_rate:.2f} %")
print(f"\n -> 物理レコード現像完了: {output_txt}")
print("="*80)
if name == "main": compiler_voynich_full_decompilation()