Beispiel #1
0
        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));
                        }
                    }
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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());
        }
Beispiel #4
0
        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);
        }