private static bool TryAggregateOnce(IEnumerable <TaggedNumberItem> items, out TaggedNumberItem result) { double aggregated = 0; foreach (TaggedNumberItem item in items) { if (aggregated == 0.5) { if (item.Number == 1 && items.Count() == 2) { result = new TaggedNumberItem() { Term = "half", Number = .5, Tag = Tag.Number }; return(true); } else { result = null; return(false); } } if (Math.Floor(item.Number) != item.Number) { aggregated = 0.5; continue; } if (aggregated == 0) { aggregated += item.Number; continue; } if (aggregated < item.Number) { if (item.Number % 100 == 0) { aggregated *= item.Number; } else { if (aggregated > 13) { aggregated *= 100; aggregated += item.Number; } else { result = null; return(false); } } } else { if (Math.Floor(Math.Log10(aggregated)) - Math.Floor(Math.Log10(item.Number)) >= 1) { aggregated += item.Number; } else { if (aggregated > 13) { aggregated *= 100; aggregated += item.Number; } else { result = null; return(false); } } } } result = new TaggedNumberItem() { Number = aggregated, Tag = items.Last().Tag, Term = String.Join(" ", items.Select(x => x.Term)) }; return(true); }
public static TaggedItem[] Aggregate(IEnumerable <TaggedItem> items) { List <TaggedItem> aggregateList = new List <TaggedItem>(); List <TaggedNumberItem> aggregateNumber = new List <TaggedNumberItem>(); int i = 0; bool isNum = false; TaggedItem andTerm = null; foreach (TaggedItem item in items) { if (item is TaggedNumberItem) { TaggedNumberItem aggregateItem; TaggedNumberItem toAdd = item as TaggedNumberItem; aggregateNumber.Add(toAdd); if (!TryAggregateOnce(aggregateNumber, out aggregateItem)) { aggregateNumber.Remove(toAdd); TryAggregateOnce(aggregateNumber, out aggregateItem); aggregateList.Add(aggregateItem); aggregateNumber.Clear(); aggregateNumber.Add(toAdd); } isNum = true; andTerm = null; } else { if (andTerm == null) { if (aggregateNumber.Count > 0 && isNum) { if (item.Term == "and") { andTerm = item; continue; } else { // Submit the deck TaggedNumberItem aggregateItem; if (TryAggregateOnce(aggregateNumber, out aggregateItem)) { aggregateList.Add(aggregateItem); } aggregateNumber.Clear(); } } } else { aggregateList.Add(andTerm); andTerm = null; } isNum = false; aggregateList.Add(item); } } if (aggregateNumber.Count > 0) { TaggedNumberItem aggregateItem; if (TryAggregateOnce(aggregateNumber, out aggregateItem)) { aggregateList.Add(aggregateItem); } aggregateNumber.Clear(); } return(aggregateList.ToArray()); }
private static bool TryParseExact(TaggedItem[] items, out ITimeEvalNode node) { if (items.Length == 0) { node = new DayLeafNode(null, 0); return(true); } else if (items.Length == 1) { TaggedItem item = items[0]; if (item is TaggedDateTimeItem) { TaggedDateTimeItem dtItem = item as TaggedDateTimeItem; // Second if (dtItem.Type == DateTimeType.Second) { node = new SecondLeafNode(item.Term); return(true); } // Minute else if (dtItem.Type == DateTimeType.Minute) { if (dtItem.Term.StartsWith("quarter")) { node = new MinuteLeafNode(item.Term, 15); } else { node = new MinuteLeafNode(item.Term); } return(true); } // Hour else if (dtItem.Type == DateTimeType.Hour) { node = new HourLeafNode(item.Term); return(true); } // DayTime else if (dtItem.Type == DateTimeType.DayTime) { if (dtItem.Term == "am" || dtItem.Term == "morning") { node = new DayTimeLeafNode(true); return(true); } else if (dtItem.Term == "pm" || dtItem.Term == "afternoon" || dtItem.Term == "evening" || dtItem.Term == "night") { node = new DayTimeLeafNode(false); return(true); } node = null; return(false); } // Today else if (dtItem.Type == DateTimeType.Today) { if (dtItem.Term == "today") { node = new TodayLeafNode(item.Term, 0); } else if (dtItem.Term == "tomorrow") { node = new TodayLeafNode(item.Term, 1); } else if (dtItem.Term == "yesterday") { node = new TodayLeafNode(item.Term, -1); } else { node = null; return(false); } return(true); } // Day else if (dtItem.Type == DateTimeType.Day) { node = new DayLeafNode(null, 1); return(true); } // Day of Week else if (dtItem.Type == DateTimeType.DayOfWeek) { if (dtItem.Term == "monday") { node = new DayOfWeekLeafNode(DayOfWeek.Monday, item.Term); return(true); } else if (dtItem.Term == "tuesday") { node = new DayOfWeekLeafNode(DayOfWeek.Tuesday, item.Term); return(true); } else if (dtItem.Term == "wednesday") { node = new DayOfWeekLeafNode(DayOfWeek.Wednesday, item.Term); return(true); } else if (dtItem.Term == "thursday") { node = new DayOfWeekLeafNode(DayOfWeek.Thursday, item.Term); return(true); } else if (dtItem.Term == "friday") { node = new DayOfWeekLeafNode(DayOfWeek.Friday, item.Term); return(true); } else if (dtItem.Term == "saturday") { node = new DayOfWeekLeafNode(DayOfWeek.Saturday, item.Term); return(true); } else if (dtItem.Term == "sunday") { node = new DayOfWeekLeafNode(DayOfWeek.Sunday, item.Term); return(true); } node = null; return(false); } // Week else if (dtItem.Type == DateTimeType.Week) { if (dtItem.Term == "fortnight") { node = new WeekLeafNode(item.Term, 2); } else { node = new WeekLeafNode(item.Term); } return(true); } // Month else if (dtItem.Type == DateTimeType.Month) { node = new MonthLeafNode(item.Term, 1); return(true); } // Month of Year else if (dtItem.Type == DateTimeType.MonthOfYear) { if (dtItem.Term == "january") { node = new MonthOfYearLeafNode(MonthOfYear.January); } else if (dtItem.Term == "feburary") { node = new MonthOfYearLeafNode(MonthOfYear.Feburary); } else if (dtItem.Term == "march") { node = new MonthOfYearLeafNode(MonthOfYear.March); } else if (dtItem.Term == "april") { node = new MonthOfYearLeafNode(MonthOfYear.April); } else if (dtItem.Term == "may") { node = new MonthOfYearLeafNode(MonthOfYear.May); } else if (dtItem.Term == "june") { node = new MonthOfYearLeafNode(MonthOfYear.June); } else if (dtItem.Term == "july") { node = new MonthOfYearLeafNode(MonthOfYear.July); } else if (dtItem.Term == "august") { node = new MonthOfYearLeafNode(MonthOfYear.August); } else if (dtItem.Term == "september") { node = new MonthOfYearLeafNode(MonthOfYear.September); } else if (dtItem.Term == "october") { node = new MonthOfYearLeafNode(MonthOfYear.October); } else if (dtItem.Term == "november") { node = new MonthOfYearLeafNode(MonthOfYear.November); } else if (dtItem.Term == "december") { node = new MonthOfYearLeafNode(MonthOfYear.December); } else { node = null; return(false); } return(true); } // Year else if (dtItem.Type == DateTimeType.Year) { if (dtItem.Term.StartsWith("centur")) { node = new YearLeaflNode(item.Term, 100); } else { node = new YearLeaflNode(item.Term); } return(true); } else { node = null; return(false); } } else if (item is TaggedNumberItem) { TaggedNumberItem numItem = item as TaggedNumberItem; // Parse hour (e.g. at four) if (numItem.Number >= 1 && numItem.Number < 12 && numItem.Tag == Tag.Number && numItem.Term != "a" && numItem.Term != "an") { node = new BinaryOperatorNode( new HourOfDayLeafNode(FindWorkHour((int)numItem.Number)), new MinuteOfHourLeafNode(0), DateTimeOperation.Additive); return(true); } // Parse day of month if (numItem.Number > 0 && numItem.Number <= 31 && numItem.Tag == Tag.NumberOrdinal) { node = new DayOfMonthLeafNode((int)numItem.Number); return(true); } // Parse year (e.g. twenty twenty) else if (numItem.Number > 1100 && numItem.Number < 2100 && numItem.Tag == Tag.Number) { node = new YearOfHistoryLeafNode((int)numItem.Number); return(true); } } node = null; return(false); } else if (items.Length == 2) { if (items[0] is TaggedNumberItem && items[1] is TaggedDateTimeItem) { ITimeEvalNode dt; TaggedNumberItem numItem = items[0] as TaggedNumberItem; if ((items[1] as TaggedDateTimeItem).Type == DateTimeType.Today) { node = null; return(false); } if (items[0].Tag == Tag.Number && numItem.Number <= 12 && (items[1] as TaggedDateTimeItem).Type == DateTimeType.HourOfDay) { node = new BinaryOperatorNode( new HourOfDayLeafNode(FindWorkHour((int)numItem.Number)), new MinuteOfHourLeafNode(0), DateTimeOperation.Additive); return(true); } if (TryParseExact(new TaggedItem[] { items[1] }, out dt)) { if (dt is TimeEvalLeafNode) { TimeEvalLeafNode dtTimespan = dt as TimeEvalLeafNode; // 4 pm if (items[0].Tag == Tag.Number && numItem.Number <= 12 && (items[1] as TaggedDateTimeItem).Type == DateTimeType.DayTime) { node = new BinaryOperatorNode( new BinaryOperatorNode( new HourOfDayLeafNode((int)numItem.Number), new MinuteOfHourLeafNode(0), DateTimeOperation.Additive), dtTimespan, DateTimeOperation.Additive); } else if (numItem.Number > 1 && !items[1].Term.EndsWith("s") && (items[1] as TaggedDateTimeItem).Type != DateTimeType.HourOfDay) { node = null; return(false); } // 4 days else { dtTimespan.Quantity *= numItem.Number; node = dt; } return(true); } } node = null; return(false); } // July 4th else if (items[0] is TaggedDateTimeItem && items[1] is TaggedNumberItem) { TaggedNumberItem numItem = items[1] as TaggedNumberItem; if (numItem.Tag == Tag.NumberOrdinal && numItem.Number < 31) { ITimeEvalNode dt; if (TryParseExact(new TaggedItem[] { items[0] }, out dt)) { if (dt is MonthOfYearLeafNode) { node = new BinaryOperatorNode( dt, new DayOfMonthLeafNode((int)numItem.Number), DateTimeOperation.Additive); return(true); } } } node = null; return(false); } // Four thirty else if (items[0] is TaggedNumberItem && items[1] is TaggedNumberItem) { if (items[0].Tag == Tag.Number && items[1].Tag == Tag.Number) { TaggedNumberItem num1 = items[0] as TaggedNumberItem; TaggedNumberItem num2 = items[1] as TaggedNumberItem; if (num1.Number <= 24 && num2.Number < 60) { node = new BinaryOperatorNode( new HourOfDayLeafNode( FindWorkHour((int)num1.Number)), new MinuteOfHourLeafNode( (int)num2.Number), DateTimeOperation.Additive); return(true); } } node = null; return(false); } node = null; return(false); } node = null; return(false); }