Regex tooling: formula gene grouping, content patches, def validation
CI / build-test (push) Successful in 1m12s

Three regex-powered content tools (phase G5):

- Formula group functions gsum/gcount/gavg/gmin/gmax('regex') aggregate
  over every context variable whose name matches the pattern, e.g.
  gsum('leaf_.*'). Adds string literals to the formula grammar and an
  IFormulaContext.ResolveMatching hook; GenomeContext enumerates matching
  genes, so a trait can sum/average a gene group.
- DefDatabase content patches: a { "type": "Patch", patches:[{ defType,
  match (regex on defName), set:{fields} }] } file sets fields on every
  matching raw def before resolution — mods patch Core in bulk.
- DefDatabase.RegisterValidator(typeKey, field, regex): load-time check
  that a string field matches a pattern, throwing otherwise (naming/format
  conventions).

Covered by FormulaTests (group aggregation, composition, bad calls) and
DefDatabaseTests (patch set/match/unknown-type, validator pass/reject).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-06-13 03:59:36 +03:00
co-authored by Claude Opus 4.8
parent ead22517ee
commit d044cafad9
8 changed files with 440 additions and 1 deletions
@@ -6,6 +6,7 @@ internal enum TokenType
{
Number,
Identifier,
String,
Plus,
Minus,
Star,
@@ -99,6 +100,27 @@ internal static class FormulaLexer
continue;
}
if (c == '\'')
{
var open = i;
var start = ++i;
while (i < source.Length && source[i] != '\'')
{
i++;
}
if (i >= source.Length)
{
throw new FormulaException($"Unterminated string at position {open}.");
}
tokens.Add(
new Token(TokenType.String, open, text: source.Substring(start, i - start))
);
i++; // пропускаем закрывающую кавычку
continue;
}
var pos = i;
switch (c)
{