feat(800-2): 수식 변수 정의 영역 서버 — 정의 칸(안 탄 갈래 뺌 · 겹침 합침 · 열쇠 글 0) · 새 기호 연결 고침 · 후보 길
- 수식 응답 새 칸 정의 — 만약 탄 갈래 표지 걸림 그대로 · 같은 기호 한 줄 · 연결 사람 말 · 값 · 단위 · DB 열쇠 없음 - 고침 할일 연결(입력 · 표 · 요소 · 로직 · 상수) · 모르는 기호 까닭 · 후보 길 M01 · M02 equation/links - 낡은 시험 test_796_1 「모르는 이름」 → 「모르는 기호」(까닭 문구 바뀜) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
{할일: 지움, 열쇠} — 쓰는 식이 있으면 막고 쓰는 곳 목록
|
||||
{할일: 변수, 열쇠, 이름?, 기호?, 위?, 아래?, 단위?} — 식은 열쇠로 부르니 안 깨짐
|
||||
{할일: 표시, 열쇠, 표시: 0~6 | null}
|
||||
{할일: 연결, 열쇠, 갈래: 입력|표|요소|로직|상수, …} — 새 기호의 연결 지정(`master_equation_link.py` 머리)
|
||||
고친 중간 줄은 `표시` 없으면 `SHOW`(보이는 자리에서 잘라 셈 · 요구 658) — 고치지 않은 줄은 그대로.
|
||||
키보드 한 줄 식 = 변수 글(기호_아래^위 · 이름 · 열쇠) · `× ÷ −` · 나머지는 엔진 식 말 그대로
|
||||
(`[노임 …]` · `[별칭]` 은 M01 · M02 층이 `M02_Sangeun_Formula.to_engine` 으로 먼저 풂).
|
||||
@@ -22,6 +23,7 @@ import re
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
import master_equation as meq
|
||||
import master_equation_link as link
|
||||
import master_formula as mf
|
||||
|
||||
KEY_FORM = re.compile(r"^[^\W\d][\w]{0,19}$") # 열쇠 = 글자로 시작 · 20 자까지
|
||||
@@ -227,12 +229,39 @@ def _text_of(ed: dict, row: dict, words) -> tuple[str, list[str]]:
|
||||
return words(text, row) if words and text else (text, [])
|
||||
|
||||
|
||||
def unknown(text: str, row: dict) -> list[str]:
|
||||
"""엔진 식 글 안 모르는 변수 글(변수 · 열쇠 · 예약어 · 함수 · 칸 · 인자 이름 · 요소 키 빼고)."""
|
||||
known = set(_names(row)[0]) | _all_keys(row) | RESERVED
|
||||
out, at = [], 0
|
||||
while at < len(text):
|
||||
if text[at] in "'[":
|
||||
end = text.find("'" if text[at] == "'" else "]", at + 1)
|
||||
at = len(text) if end < 0 else end + 1
|
||||
continue
|
||||
m = None if at and text[at - 1].isalnum() else _TOKEN.match(text, at)
|
||||
if not m:
|
||||
at += 1
|
||||
continue
|
||||
word, before, rest = m.group(), text[:at].rstrip(), text[m.end() :].lstrip()
|
||||
at = m.end()
|
||||
arg = rest.startswith("=") and not rest.startswith("==")
|
||||
skip = before.endswith(".") or rest.startswith("(") or arg
|
||||
if not (skip or word in known or mf.mk.KEY.fullmatch(word) or word in out):
|
||||
out.append(word)
|
||||
return out
|
||||
|
||||
|
||||
def _set_formula(row: dict, ed: dict, why: list, spots: set, words=None) -> None:
|
||||
spot = str(ed.get("자리") or "")
|
||||
text, bad = _text_of(ed, row, words)
|
||||
if bad:
|
||||
why += [f"{spot} · {w}" for w in bad]
|
||||
return
|
||||
if not isinstance(ed.get("나무"), dict) and (miss := unknown(text, row)):
|
||||
why.append(
|
||||
f"{spot} · 모르는 기호 「{'」 「'.join(miss)}」 — 변수 정의 영역에서 연결을 지정"
|
||||
)
|
||||
return
|
||||
if not text:
|
||||
why.append(f"{spot} · 식이 빔")
|
||||
return
|
||||
@@ -383,6 +412,9 @@ def apply(master, row: dict, edits: list, words=None) -> tuple[dict, list[str],
|
||||
_look(new, key, ed, why)
|
||||
elif job == "표시":
|
||||
_show(new, key, ed, why)
|
||||
elif job == "연결":
|
||||
add, bad = link.plan(master, ed)
|
||||
_add(new, add, why, spots, words) if add else why.append(bad)
|
||||
else:
|
||||
why.append(f"모르는 할일 「{job}」")
|
||||
except (mf.FormulaError, KeyError, TypeError, ValueError) as e:
|
||||
|
||||
Reference in New Issue
Block a user