gec-inline / gec /parse.py
Lopato4ka's picture
Upload folder using huggingface_hub
32387a0 verified
Raw
History Blame Contribute Delete
1.98 kB
"""Parse the inline bracket format back into a clean corrected sentence.
The renderer guarantees a well-formed string, but model output may be
malformed (missing brace, nested, extra whitespace). The parser is
tolerant: anything it cannot understand as `{src=>tgt}` is passed
through as plain text.
Public API:
parse_inline(text) -> (corrected_sentence, edits, parse_ok)
recover_correction(text) -> corrected_sentence only (shortcut)
Edit tuples returned are (src_tokens: list[str], tgt_tokens: list[str]),
matching the BEA/ERRANT convention of whitespace-tokenized spans.
"""
from __future__ import annotations
import re
from dataclasses import dataclass
# Match {SRC=>TGT}. Both sides can be empty. We are permissive about
# whitespace adjacent to `=>` and inside the braces.
_BRACKET_RE = re.compile(r"\{([^{}=]*?)=>([^{}=]*?)\}")
@dataclass
class ParsedEdit:
src: list[str]
tgt: list[str]
def parse_inline(text: str) -> tuple[str, list[ParsedEdit], bool]:
"""Return (corrected_text, edits, parse_ok).
parse_ok is False when the input contains an unmatched brace
(`{` or `}` that the bracket regex did not consume) — caller may
fall back to treating the raw text as the corrected sentence.
"""
edits: list[ParsedEdit] = []
def _sub(m: re.Match) -> str:
src = m.group(1).strip().split()
tgt = m.group(2).strip().split()
edits.append(ParsedEdit(src=src, tgt=tgt))
return m.group(2).strip()
replaced = _BRACKET_RE.sub(_sub, text)
# Unmatched braces left behind -> the output was malformed.
parse_ok = "{" not in replaced and "}" not in replaced
# Strip duplicate spaces that arise from deletions / empty inserts.
cleaned = re.sub(r"\s+", " ", replaced).strip()
return cleaned, edits, parse_ok
def recover_correction(text: str) -> str:
"""Shortcut: return only the corrected sentence."""
corrected, _, _ = parse_inline(text)
return corrected