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