Skip to content

[m100] exam_science.hwp 20번 응답 수식 (timesm / simZ) — 수식 토크나이저 keyword prefix-split 누락 #576

@planet6897

Description

@planet6897

증상

`samples/exam_science.hwp` 페이지 4 20번 응답 paragraph " 는? (단, 는 임의의 원소 기호이다.) [3점]" 의 인라인 수식이 잘못 렌더됨.

작업지시자 보고: "수식이 잘못나타남"

위치

pi=128 (page 4 우측 col), 2 개 inline 수식:

--- 문단 0.128 --- cc=46 text_len=29 controls=2
  [0] 수식: script=\"{b} over {a timesm}\"  tac=true w=3108 h=2580 (분수, TALL)
  [1] 수식: script=\"rm X simZ\"             tac=true w=2708 h=1125
  ls[0]: vpos=67483 lh=2580 sw=30562 cs=1130

paragraph 위치는 정상 (Tasks #568/#573 fix 와 무관 — 인라인 표 없음, narrow segment_width 없음).

SVG 측 — 수식 위치는 정상이나 콘텐츠 잘못 렌더

  • ctrl[0] "{b} over {a timesm}" 분수 transform: (560.87, 1040.49) ✓ 정상 위치
  • ctrl[1] "rm X simZ" transform: (650.31, 1045.69) ✓ 정상 위치

잘못 렌더된 콘텐츠:

ctrl[0] 분수의 분모:

<text x=\"2.93\" font-style=\"italic\">a</text>
<text x=\"11.40\" font-style=\"italic\">timesm</text>

→ "a × m" 이어야 하나 "a timesm" (italic 식별자) 으로 표시

ctrl[1]:

<text x=\"0.00\">X</text>          ← rm 모디파이어로 upright 정상
<text x=\"10.01\" font-style=\"italic\">simZ</text>

→ "X ~ Z" (또는 "X ≈ Z" 등 sim 연산자) 이어야 하나 "X simZ" (italic 식별자) 으로 표시

본질 결함

src/renderer/equation/tokenizer.rs::read_command (L101-124) 가 keyword prefix-split 을 "rm / it / bold" 3 개만 처리:

fn read_command(&mut self) -> Token {
    for kw in [\"bold\", \"it\", \"rm\"] {       // ← prefix-split 대상이 3개 뿐
        if self.matches_at(kw) {
            let after = self.peek(kw.len());
            if matches!(after, Some(c) if c.is_ascii_alphanumeric()) {
                self.pos += kw.len();
                return Token::new(TokenType::Command, kw, start);
            }
        }
    }
    // 그 외: 연속 alphanumeric 을 단일 토큰으로 — 결함 발현
    while let Some(ch) = self.current() {
        if ch.is_ascii_alphanumeric() { value.push(ch); ... } else { break; }
    }
}

결과:

  • "timesm" 입력 → 단일 Command 토큰 "timesm" (기대: "times" + "m")
  • "simZ" 입력 → 단일 Command 토큰 "simZ" (기대: "sim" + "Z")

"times" 는 `symbols.rs::lookup_symbol("times")` 가 "×" 로 매핑되는 known keyword. "sim" 도 마찬가지. 그러나 토크나이저가 keyword 경계를 인식하지 못해 단일 식별자로 처리됨.

정정 방향 후보

안 A — read_command 의 prefix-split 키워드 목록 확장

"bold/it/rm" 외에 `symbols.rs` 에 등록된 known keyword (times, sim, over, sqrt, alpha, beta, cdot, ... 등 수십 개) 를 모두 prefix-split 대상으로 추가.

단점: 키워드 목록 유지보수 부담. `lookup_symbol` / `symbols.rs` 와 동기화 필요.

안 B — Longest-prefix matching against known keyword set

토큰 시작 시 `symbols.rs` 등록 keyword 와 longest-prefix match 시도. 매치되고 다음 char 가 alphanumeric 이면 prefix 만 분리.

장점: 키워드 목록 단일화 (symbols.rs).
단점: 매번 lookup 비용. 그리스 문자 등 짧은 keyword 가 다른 식별자에 잘못 매치될 가능성 (예: "alphabet" → "alpha" + "bet")?

안 C — Word boundary heuristic

"timesm" 처럼 keyword 가 contiguous text 에 묻혀있는 케이스만 휴리스틱으로 분리 (예: 입력이 "keyword + non-keyword" 패턴일 때만 분리).

단점: 휴리스틱 — 메모리 `feedback_rule_not_heuristic` 정합 위반 가능. 룰 vs 휴리스틱 자문 필요.

Stage 1 진단 후 결정.

영향 범위

광범위 sweep 으로 다른 fixture 의 수식 script 점검 필요:

  • exam_science.hwp 의 다른 paragraph 도 동일 패턴 가능 (예: pi=49 "는 와 으로" + 수식 등)
  • exam_eng / exam_kor / exam_math 등 시험지 fixture
  • atop-equation-01.hwp / equation-lim.hwp 등 수식 전용 fixture

우선순위

시각 정확성 — 수식 의미 변경 (곱셈 연산자 / 유사 연산자 표시 누락). M100 milestone.

참고

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions