Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
"""도메인 용어 사전 로더 (계획서 §5.6, 수정사항 4번).
|
|
|
|
`config/domain_glossary.yaml` 은 의존성을 늘리지 않으려고 YAML 파서 없이 읽는다.
|
|
지원 형식은 한 줄 리스트뿐이다:
|
|
|
|
총계정원장: [G/L, GL, 원장, ACDOCA, SKAT, FAGLL03]
|
|
|
|
질의 확장(query/expand.py)과 concepts 위키 생성(wiki_out/run.py)이 같은 사전을 쓰도록
|
|
로딩을 여기로 모았다 (이전에는 wiki_out/run.py 안에 인라인 정규식으로만 있었다).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from functools import lru_cache
|
|
from pathlib import Path
|
|
|
|
from .settings import ROOT
|
|
|
|
# "용어: [동의어, 동의어]" — 주석(#)·빈 줄·중첩 키(tags:)는 건너뛴다
|
|
GLOSSARY_LINE = re.compile(r"^([^#:\s][^:]*):\s*\[(.*)\]\s*$")
|
|
|
|
DEFAULT_PATH = ROOT / "config" / "domain_glossary.yaml"
|
|
|
|
|
|
def parse_glossary(text: str) -> dict[str, list[str]]:
|
|
"""사전 텍스트 → {대표어: [동의어...]}"""
|
|
out: dict[str, list[str]] = {}
|
|
for line in text.splitlines():
|
|
m = GLOSSARY_LINE.match(line.strip())
|
|
if not m:
|
|
continue
|
|
term = m.group(1).strip()
|
|
syns = [t.strip() for t in m.group(2).split(",") if t.strip()]
|
|
if term:
|
|
out[term] = syns
|
|
return out
|
|
|
|
|
|
@lru_cache(maxsize=4)
|
|
def load_glossary(path: Path | None = None) -> dict[str, list[str]]:
|
|
p = path or DEFAULT_PATH
|
|
if not p.exists():
|
|
return {}
|
|
return parse_glossary(p.read_text(encoding="utf-8"))
|
|
|
|
|
|
@lru_cache(maxsize=4)
|
|
def synonym_map(path: Path | None = None) -> dict[str, list[str]]:
|
|
"""양방향 동의어 맵 — 대표어로도, 동의어로도 질의가 들어올 수 있다.
|
|
|
|
"입고" → [GR, MSEG, 101 …] 뿐 아니라 "GR" → [입고, MSEG …] 도 성립해야 한다.
|
|
키는 대문자 정규화(한글은 그대로)해 비교한다.
|
|
"""
|
|
glossary = load_glossary(path)
|
|
groups: list[set[str]] = [{term, *syns} for term, syns in glossary.items()]
|
|
out: dict[str, list[str]] = {}
|
|
for group in groups:
|
|
for member in group:
|
|
key = member.upper()
|
|
others = [m for m in group if m.upper() != key]
|
|
if not others:
|
|
continue
|
|
bucket = out.setdefault(key, [])
|
|
for o in others:
|
|
if o not in bucket:
|
|
bucket.append(o)
|
|
return out
|