bilegentile's picture
Upload folder using huggingface_hub
c19ca42 verified
raw
history blame contribute delete
2.69 kB
from __future__ import annotations
import re
class ReplacementInterpolation:
def __init__(self, name: str):
self.name = name
class ReplacementString:
"""
A parser and interpolator for chainner's string replacement patterns.
The syntax is as follows (ANTLR 4):
Pattern: ( LiteralChar | EscapedChar | Interpolation )* ;
LiteralChar: ~[{] ; // any character except "{"
EscapedChar: '{{' ;
Interpolation: '{' InterpolationContent '}' ;
InterpolationContent: [A-Za-z0-9]+ ;
"""
def __init__(self, pattern: str):
self.tokens: list[str | ReplacementInterpolation] = []
self.names: set[str] = set()
content_pattern = re.compile(r"\A\w+\Z")
lastIndex = 0
lastStr = ""
for m in re.compile(r"(\{\{)|\{([^{}]*)\}").finditer(pattern):
lastStr += pattern[lastIndex : m.start()]
lastIndex = m.end()
interpolation = m.group(2)
if interpolation is not None:
if interpolation == "":
raise ValueError(
"Invalid replacement pattern. {} is not a valid replacement."
""" Either specify a name or id number, or escape a single "{" as "{{"."""
f" Full pattern: {pattern}"
)
if content_pattern.fullmatch(interpolation) is None:
raise ValueError(
"Invalid replacement pattern."
f" {{{interpolation}}} is not a valid replacement."
" Names and ids only allow letters and digits."
f" Full pattern: {pattern}"
)
self.tokens.append(lastStr)
lastStr = ""
self.tokens.append(ReplacementInterpolation(interpolation))
self.names.add(interpolation)
else:
lastStr += "{"
lastStr += pattern[lastIndex:]
self.tokens.append(lastStr)
def replace(self, replacements: dict[str, str]) -> str:
result = ""
for token in self.tokens:
if isinstance(token, str):
result += token
else:
if token.name in replacements:
result += replacements[token.name]
else:
raise ValueError(
"Unknown replacement."
f" There is no replacement with the name or id {token.name}."
f" Available replacements: {', '.join(replacements.keys()) }."
)
return result