Download tagger/conllu.py from Ericu950/Stoicheia-code: direct link, hf CLI and curl.
- Browser
- Download file 2.49 kB
-
https://huggingface.co/Ericu950/Stoicheia-code/resolve/main/tagger/conllu.py
- Command line
-
hf download hf://Ericu950/Stoicheia-code/tagger/conllu.py
-
curl -L -o conllu.py https://huggingface.co/Ericu950/Stoicheia-code/resolve/main/tagger/conllu.py
2.49 kB
| """Minimal stdlib CoNLL-U reader/writer for the OGA kfold treebank. | |
| Keeps only what the tagger needs (FORM/LEMMA/UPOS/XPOS per syntactic word) but | |
| round-trips every other column and comment untouched, so predictions can be written | |
| into a copy of the gold file and scored with the official conll18 script. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| from typing import Iterator | |
| class Token: | |
| tid: str # "1", "2", ... (kept as string; MWT ranges and empty nodes never land here) | |
| form: str | |
| lemma: str | |
| upos: str | |
| xpos: str | |
| feats: str | |
| head: str | |
| deprel: str | |
| deps: str | |
| misc: str | |
| class Sentence: | |
| tokens: list[Token] = field(default_factory=list) | |
| # raw lines in original order, as (kind, payload): kind "comment" | "mwt" | "empty" -> raw | |
| # line, kind "token" -> index into tokens. Preserves exact file structure on write. | |
| lines: list[tuple[str, object]] = field(default_factory=list) | |
| def read_conllu(path) -> Iterator[Sentence]: | |
| sent = Sentence() | |
| with open(path, encoding="utf-8") as f: | |
| for line in f: | |
| line = line.rstrip("\n") | |
| if not line: | |
| if sent.lines: | |
| yield sent | |
| sent = Sentence() | |
| continue | |
| if line.startswith("#"): | |
| sent.lines.append(("comment", line)) | |
| continue | |
| cols = line.split("\t") | |
| tid = cols[0] | |
| if "-" in tid: | |
| sent.lines.append(("mwt", line)) | |
| elif "." in tid: | |
| sent.lines.append(("empty", line)) | |
| else: | |
| sent.lines.append(("token", len(sent.tokens))) | |
| sent.tokens.append(Token(*cols[:10])) | |
| if sent.lines: | |
| yield sent | |
| def write_conllu(sents, preds, path): | |
| """preds: list (per sentence) of lists of (lemma, upos, xpos) aligned with sent.tokens.""" | |
| with open(path, "w", encoding="utf-8") as f: | |
| for sent, ps in zip(sents, preds): | |
| for kind, payload in sent.lines: | |
| if kind == "token": | |
| t = sent.tokens[payload] | |
| lemma, upos, xpos = ps[payload] | |
| f.write("\t".join([t.tid, t.form, lemma, upos, xpos, | |
| t.feats, t.head, t.deprel, t.deps, t.misc]) + "\n") | |
| else: | |
| f.write(payload + "\n") | |
| f.write("\n") | |