public Schedule Parse(string parseThis) { var schedule = new Schedule(); var parts = new PartsTraverser(ParseParts(parseThis)); ParseBigLoop(parts, schedule); return schedule; }
private void ParseBigLoop(PartsTraverser parts, Schedule schedule) { var days = new List<Tuple<int, Interval>>(); do { if (parts.NextIf("every")) { if (parts.NextIf("day") || parts.Peek("hour")) { days.AddRange( new[] { Tuple.Create(0, Interval.Week), Tuple.Create(1, Interval.Week), Tuple.Create(2, Interval.Week), Tuple.Create(3, Interval.Week), Tuple.Create(4, Interval.Week), Tuple.Create(5, Interval.Week), Tuple.Create(6, Interval.Week) }); } else // weekday { do { var nextDay = parts.NextPart(); days.Add(Tuple.Create(Array.IndexOf(_days, nextDay), Interval.Week)); } while (parts.NextIf("and")); } } else if (_days.Any(x => x == parts.Peek())) { do { var nextDay = parts.NextPart(); days.Add(Tuple.Create(Array.IndexOf(_days, nextDay), Interval.Week)); parts.SkipAnyOrFail("s"); } while (parts.NextIf("and")); } else if (IsNumeric(parts.Peek()) || parts.Peek("last")) { var scopeDays = new List<int>(); do { if (parts.NextIf("last")) { scopeDays.Add(-1); } else { var nth = int.Parse(parts.NextPart()) - 1; parts.SkipIf("st", "nd", "rd", "th"); if (parts.NextIf("last")) { nth = -1 - nth; } scopeDays.Add(nth); } } while (parts.NextIf("and")); parts.SkipAnyOrFail("day"); parts.SkipAnyOrFail("every"); if (parts.NextIf("week")) { scopeDays.ForEach(x => days.Add(Tuple.Create(x, Interval.Week))); } else if (parts.NextIf("month")) { scopeDays.ForEach(x => days.Add(Tuple.Create(x, Interval.Month))); } else if (parts.NextIf("year")) { scopeDays.ForEach(x => days.Add(Tuple.Create(x, Interval.Year))); } else { throw new ParsingException("Unexpected token " + parts.Peek() + ". Expected week, month or year."); } } } while (parts.NextIf("and")); days = days.Distinct().ToList(); schedule.Times = ParseTimes(parts); schedule.Days = days; }