/// <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)))); }
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); } }
/// <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); }