/// <summary> /// Expand pattern into an (almost) equivalent one, but with single Either. /// Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d) /// Quirks: [-a] => (-a), (-a...) => (-a -a) /// </summary> /// <param name="pattern"></param> /// <returns></returns> public static Either Transform(Pattern pattern) { var result = new List<IList<Pattern>>(); var groups = new List<IList<Pattern>> {new List<Pattern> {pattern}}; while (groups.Count > 0) { var children = groups[0]; groups.RemoveAt(0); var parents = new[] { typeof (Required), typeof (Optional), typeof (OptionsShortcut), typeof (Either), typeof (OneOrMore) }; if (parents.Any(t => children.Any(c => c.GetType() == t))) { var child = children.First(c => parents.Contains(c.GetType())); children.Remove(child); if (child is Either) { foreach (var c in (child as Either).Children) { var l = new List<Pattern> {c}; l.AddRange(children); groups.Add(l); } } else if (child is OneOrMore) { var l = new List<Pattern>(); l.AddRange((child as OneOrMore).Children); l.AddRange((child as OneOrMore).Children); // add twice l.AddRange(children); groups.Add(l); } else { var l = new List<Pattern>(); if (child.HasChildren) l.AddRange(child.Children); l.AddRange(children); groups.Add(l); } } else { result.Add(children); } } return new Either(result.Select(r => new Required(r.ToArray()) as Pattern).ToArray()); }
public SingleMatchResult(int index, Pattern match) { Position = index; Match = match; }