public static IEnumerable <DateTime> Extract(string source, DateTime dateTimeEval) { string[] tokens = Tokenizer.Tokenize(source); TaggedItem[] items = new TagFactory( new NumberTagger(), new OperatorTagger(), new DateTimeTagger(), new IgnoreTagger()) .Tag(tokens); TaggedItem[] aggregatedItems = NumberAggregator.Aggregate(items); bool[] coverageMap = new bool[aggregatedItems.Length]; for (int i = 0; i < aggregatedItems.Length; i++) { for (int j = aggregatedItems.Length - 1; j >= i; j--) { if (!isCovered(coverageMap, i, j)) { TaggedItem[] partial = new TaggedItem[j - i + 1]; Array.Copy(aggregatedItems, i, partial, 0, j - i + 1); ITimeEvalNode node; if (DateTimeParser.TryParse(partial, out node)) { for (int index = i; index <= j; index++) { coverageMap[index] = true; } yield return(node.GetCurrentValue(dateTimeEval)); } } } } }
public TaggedItem[] Tag(string[] tokens) { TaggedItem[] items = new TaggedItem[tokens.Length]; foreach (ITagger tagger in this.Taggers) { foreach (TaggedItem item in tagger.Tag(tokens)) { if (!this.IdentifiedItems.ContainsKey(item.TokenIndex)) { this.IdentifiedItems.Add(item.TokenIndex, item); } } } for (int index = 0; index < tokens.Length; index++) { TaggedItem item; if (this.IdentifiedItems.TryGetValue(index, out item)) { items[index] = item; } else { items[index] = new TaggedItem() { TokenIndex = index, Tag = null, Term = tokens[index] }; } } return(items); }
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); }