/// <summary> /// Reads a specific rule from the input. The rule is given in the format: /// 80: 116 116 | 119 134 /// Where the '|' character seperates alternative sub-rules. /// </summary> /// <param name="input">The input.</param> /// <returns>The list of sub-rules.</returns> private List <Rule> ReadRule(string input) { var subRules = input .Split(new[] { " | " }, StringSplitOptions.None) .Select(x => x.Split().ToList()) .ToList(); var rules = new List <Rule>(); foreach (var subRule in subRules) { if (subRule.Count == 1 && subRule[0].Contains("\"")) { var rule = new RuleToken() { Value = subRule[0][1] }; rules.Add(rule); } else { var rule = new RuleSequence() { Nodes = subRule .Select(x => int.Parse(x)) .ToList() }; rules.Add(rule); } } return(rules); }
/// <summary> /// Consumes a single character, and returns the new position (as /// an enumerator to match other consume methods). /// </summary> /// <param name="message">The message.</param> /// <param name="rule">The rule.</param> /// <param name="position">The current position.</param> /// <returns>The next position.</returns> private IEnumerable <int> ConsumeRule(string message, RuleToken rule, int position) { if (position >= message.Length) { yield break; } var expected = rule.Value; if (message[position] == expected) { yield return(position + 1); } }