private static ISet <string> ValidateReferencedMatchersList( IReadOnlyList <IReferencedMatchers> referencedMatchersList) { var knownReferences = new HashSet <string>(); foreach (var referencedMatchers in referencedMatchersList) { var referenceName = referencedMatchers.ReferenceName; List <string> regexes = referencedMatchers.Data.Select(d => d.Regex).ToList(); ValidateGroupNames(regexes); if (regexes.Any(s => s.Contains(ValuePlaceholder))) { throw new ParseException( $"A regex of reference {referenceName} contains values"); } if (regexes.Any(s => ReferencePlaceholderRegex.IsMatch(s))) { throw new ParseException( $"A regex of reference {referenceName} contains references"); } if (!knownReferences.Add(referenceName)) { throw new ParseException( $"The reference name {referenceName} is not unique between the IReferencedMatchers"); } } return(knownReferences); }
private static IReadOnlyDictionary <string, ISet <string> > ValidateStatMatchersList( IReadOnlyList <IStatMatchers> statMatchersList, ISet <string> knownReferences) { var recursiveReferences = new Dictionary <string, ISet <string> >(); foreach (var statMatchers in statMatchersList) { var referenceNames = statMatchers.ReferenceNames; List <string> regexes = statMatchers.Data.Select(d => d.Regex).ToList(); ValidateGroupNames(regexes); if (referenceNames.IsEmpty()) { continue; } if (regexes.Any(s => s.Contains(ValuePlaceholder))) { throw new ParseException( $"A regex of reference {string.Join(",", referenceNames)} contains values"); } foreach (var referenceName in referenceNames) { if (knownReferences.Contains(referenceName)) { throw new ParseException( $"The reference name {referenceName} is used by both an IReferencedMatchers and an IStatMatchers"); } var containedReferences = regexes .SelectMany(r => ReferencePlaceholderRegex.Matches(r).Cast <Match>()) .Select(m => m.Groups[1].Value); recursiveReferences.GetOrAdd(referenceName, _ => new HashSet <string>()) .UnionWith(containedReferences); } } knownReferences.UnionWith(recursiveReferences.Keys); return(recursiveReferences); }
private string ExpandReferences(string regex, string referencePrefix) { var referenceIndex = 0; return(ReferencePlaceholderRegex.Replace(regex, match => { var referenceName = match.Groups[1].Value; var prefix = _regexGroupFactory.CombineGroupPrefixes(referencePrefix, referenceIndex.ToString()); referenceIndex++; var indexedReferencedRegexes = _referencedRegexes.GetRegexes(referenceName) .Select((matcher, index) => (matcher, index)); IEnumerable <string> regexes = from t in indexedReferencedRegexes // Without ordering, e.g. "Has a" in "(Has|Has a)" would never be matched orderby t.matcher.Length descending // Recursive expansion let innerRegex = ExpandReferences(t.matcher, prefix) select _regexGroupFactory.CreateReferenceGroup(prefix, referenceName, t.index, innerRegex); var joinedRegex = string.Join("|", regexes); return $"({joinedRegex})"; })); }