/// <summary>
 /// Construct a parser that matches one or more instances of applying <paramref name="parser"/>.
 /// </summary>
 /// <typeparam name="T">The type of value being parsed.</typeparam>
 /// <param name="parser">The parser.</param>
 /// <returns>The resulting parser.</returns>
 public static TextParser <T[]> AtLeastOnce <T>(this TextParser <T> parser)
 {
     if (parser == null)
     {
         throw new ArgumentNullException(nameof(parser));
     }
     return(parser.Then(first => parser.Many().Select(rest => ArrayEnumerable.Cons(first, rest))));
 }
Пример #2
0
        private static void TestArrayEnumerator()
        {
            var myEnum = new ArrayEnumerable<string>(5);
            myEnum.Set(0, "Zero");
            myEnum.Set(1, "One");
            myEnum.Set(2, "Two");
            myEnum.Set(3, "Three");
            myEnum.Set(4, "Four");

            foreach (var s in myEnum)
            {
                Console.WriteLine(s);
            }
        }
Пример #3
0
        /// <summary>
        /// Combine two empty results.
        /// </summary>
        /// <typeparam name="T">The source type.</typeparam>
        /// <param name="first">The first value to combine.</param>
        /// <param name="second">The second value to combine.</param>
        /// <returns>A result of type <typeparamref name="T"/> carrying information from both results.</returns>
        public static Result <T> CombineEmpty <T>(Result <T> first, Result <T> second)
        {
            if (first.Remainder != second.Remainder)
            {
                return(second);
            }

            var expectations = first.Expectations;

            if (expectations == null)
            {
                expectations = second.Expectations;
            }
            else if (second.Expectations != null)
            {
                expectations = ArrayEnumerable.Concat(first.Expectations, second.Expectations);
            }

            return(new Result <T>(second.Remainder, second.ErrorMessage, expectations, second.Backtrack));
        }
        /// <summary>
        /// Construct a parser that matches <paramref name="parser"/> zero or more times, delimited by <paramref name="delimiter"/>.
        /// </summary>
        /// <typeparam name="T">The type of value being parsed.</typeparam>
        /// <typeparam name="U">The type of the resulting value.</typeparam>
        /// <param name="parser">The parser.</param>
        /// <param name="delimiter">The parser that matches the delimiters.</param>
        /// <returns>The resulting parser.</returns>
        public static TextParser <T[]> ManyDelimitedBy <T, U>(this TextParser <T> parser, TextParser <U> delimiter)
        {
            if (parser == null)
            {
                throw new ArgumentNullException(nameof(parser));
            }
            if (delimiter == null)
            {
                throw new ArgumentNullException(nameof(delimiter));
            }

            return(parser.Then(first => delimiter.IgnoreThen(parser).Many().Select(rest => ArrayEnumerable.Cons(first, rest)))
                   .OptionalOrDefault(new T[0]));
        }
        /// <summary>
        /// Construct a parser that matches one or more instances of applying <paramref name="parser"/>, delimited by <paramref name="delimiter"/>.
        /// </summary>
        /// <typeparam name="TKind">The kind of the tokens being parsed.</typeparam>
        /// <typeparam name="T">The type of value being parsed.</typeparam>
        /// <typeparam name="U">The type of the resulting value.</typeparam>
        /// <param name="parser">The parser.</param>
        /// <param name="delimiter">The parser that matches the delimiters.</param>
        /// <returns>The resulting parser.</returns>
        public static TokenListParser <TKind, T[]> AtLeastOnceDelimitedBy <TKind, T, U>(this TokenListParser <TKind, T> parser, TokenListParser <TKind, U> delimiter)
        {
            if (parser == null)
            {
                throw new ArgumentNullException(nameof(parser));
            }
            if (delimiter == null)
            {
                throw new ArgumentNullException(nameof(delimiter));
            }

            return(parser.Then(first => delimiter.IgnoreThen(parser).Many().Select(rest => ArrayEnumerable.Cons(first, rest))));
        }
        protected IEnumerable <Item> evaluate(Predicate predicate, bool sortNeeded)
        {
            IEnumerable <Item> iterator = null;

            if (predicate is Predicate.Compare)
            {
                Predicate.Compare cmp = (Predicate.Compare)predicate;
                int id;
                if (!db.name2id.TryGetValue(cmp.name, out id))
                {
                    return(getEmptyResultSet());
                }
                Index  index = (Index)db.storage.GetObjectByOID(id);
                Object value = cmp.value;
                switch (cmp.oper)
                {
                case Predicate.Compare.Operation.Equals:
                {
                    Key key = createKey(value, true);
                    return(new Item.ItemEnumerable(index.Range(key, key)));
                }

                case Predicate.Compare.Operation.LessThan:
                    return(new Item.ItemEnumerable(index.Range(null, createKey(value, false))));

                case Predicate.Compare.Operation.LessOrEquals:
                    iterator = new Item.ItemEnumerable(index.Range(null, createKey(value, true)));
                    break;

                case Predicate.Compare.Operation.GreaterThan:
                    iterator = new Item.ItemEnumerable(index.Range(createKey(value, false), null));
                    break;

                case Predicate.Compare.Operation.GreaterOrEquals:
                    iterator = new Item.ItemEnumerable(index.Range(createKey(value, true), null));
                    break;

                case Predicate.Compare.Operation.StartsWith:
                    iterator = new Item.ItemEnumerable(index.StartsWith(((String)value).ToLower()));
                    break;

                case Predicate.Compare.Operation.IsPrefixOf:
                    iterator = new ArrayEnumerable(index.PrefixSearch(((String)value).ToLower()));
                    break;

                case Predicate.Compare.Operation.InArray:
                {
                    OidEnumerable dst = new OidEnumerable(db);
                    if (value is String[])
                    {
                        String[] arr = (String[])value;
                        for (int i = 0; i < arr.Length; i++)
                        {
                            Key key = new Key(arr[i].ToLower());
                            PersistentEnumerator src = (PersistentEnumerator)index.GetEnumerator(key, key);
                            while (src.MoveNext())
                            {
                                dst.add(src.CurrentOid);
                            }
                        }
                    }
                    else if (value is double[])
                    {
                        double[] arr = (double[])value;
                        for (int i = 0; i < arr.Length; i++)
                        {
                            Key key = new Key(arr[i]);
                            PersistentEnumerator src = (PersistentEnumerator)index.GetEnumerator(key, key);
                            while (src.MoveNext())
                            {
                                dst.add(src.CurrentOid);
                            }
                        }
                    }
                    else
                    {
                        Item[] arr = (Item[])value;
                        for (int i = 0; i < arr.Length; i++)
                        {
                            Key key = new Key(arr[i]);
                            PersistentEnumerator src = (PersistentEnumerator)index.GetEnumerator(key, key);
                            while (src.MoveNext())
                            {
                                dst.add(src.CurrentOid);
                            }
                        }
                    }
                    dst.uniq();
                    return(dst);
                }
                }
            }
            else if (predicate is Predicate.And)
            {
                Predicate.And and = (Predicate.And)predicate;
                return(new JoinEnumerable(db, evaluate(and.left, true), evaluate(and.right, true)));
            }
            else if (predicate is Predicate.Or)
            {
                Predicate.Or or = (Predicate.Or)predicate;
                return(new MergeEnumerable(db, evaluate(or.left, true), evaluate(or.right, true)));
            }
            else if (predicate is Predicate.Between)
            {
                Predicate.Between between = (Predicate.Between)predicate;
                int id;
                if (!db.name2id.TryGetValue(between.name, out id))
                {
                    return(getEmptyResultSet());
                }
                Index index = (Index)db.storage.GetObjectByOID(id);
                iterator = new Item.ItemEnumerable(index.Range(createKey(between.from, true), createKey(between.till, true)));
            }
            else if (predicate is Predicate.Match)
            {
                Predicate.Match match = (Predicate.Match)predicate;
                iterator = new FullTextSearchResultEnumerable(db.root.fullTextIndex.Search(match.query, db.language, match.maxResults, match.timeLimit));
            }
            else if (predicate is Predicate.In)
            {
                Predicate.In isIn = (Predicate.In)predicate;
                int          id;
                if (!db.name2id.TryGetValue(isIn.name, out id))
                {
                    return(getEmptyResultSet());
                }
                Index         index = (Index)db.storage.GetObjectByOID(id);
                OidEnumerable dst   = new OidEnumerable(db);
                foreach (Item item in evaluate(isIn.subquery, false))
                {
                    Key key = new Key(item);
                    PersistentEnumerator src = (PersistentEnumerator)index.GetEnumerator(key, key);
                    while (src.MoveNext())
                    {
                        dst.add(src.CurrentOid);
                    }
                }
                dst.uniq();
                return(dst);
            }
            else
            {
                return(null);
            }
            return(sortNeeded ? sortResult(iterator) : iterator);
        }