Пример #1
0
        public static Parser <TToken, IEnumerable <T> > Many <TToken, T>(this Parser <TToken, T> parser)
        {
            if (parser == null)
            {
                throw new ArgumentNullException(nameof(parser));
            }

            return((i, n) =>
            {
                var rest = i;
                var result = new List <T>();
                var r = parser(i, n);
                while (r.IsSuccess)
                {
                    if (rest.Equals(r.Rest))
                    {
                        break;
                    }
                    result.Add(r.Value);
                    rest = r.Rest;
                    r = parser(rest, n);
                }

                return ParserResult <TToken, IEnumerable <T> > .Success(rest, result);
            });
        }
Пример #2
0
 internal static Parser <char, T> TryConvert <T>(string str, Func <string, T> converter)
 {
     return((i, n) =>
     {
         try
         {
             return ParserResult <char, T> .Success(i, converter(str));
         }
         catch (FormatException)
         {
             return ParserResult <char, T> .Failure(i, $"Failed to parse {str}");
         }
     });
 }
        public static Parser <ScriptToken, ScriptToken> ScriptToken(Func <int, bool> predicate, string expected)
        {
            return(i =>
            {
                if (i.AtEnd)
                {
                    return ParserResult <ScriptToken, ScriptToken> .Failure(i, new[] { expected }, "Unexpected end of input");
                }

                if (predicate(i.GetCurrent().Tag))
                {
                    return ParserResult <ScriptToken, ScriptToken> .Success(i.Advance(), i.GetCurrent());
                }
                return ParserResult <ScriptToken, ScriptToken> .Failure(i, $"Unexpected {i.GetCurrent()}");
            });
        }
Пример #4
0
        public static Parser <TToken, IEnumerable <T> > Repeat <TToken, T>(
            this Parser <TToken, T> parser,
            int minimumCount,
            int maximumCount
            )
        {
            if (parser == null)
            {
                throw new ArgumentNullException(nameof(parser));
            }

            return((i, net) =>
            {
                var remainder = i;
                var result = new List <T>();

                for (var n = 0; n < maximumCount; ++n)
                {
                    var r = parser(remainder, net);

                    if (!r.IsSuccess && n < minimumCount)
                    {
                        var what = r.Rest.AtEnd
                                                                ? "end of input"
                                                                : r.Rest.GetCurrent().ToString();

                        var msg = $"Unexpected '{what}'";
                        var exp = minimumCount == maximumCount
                                                                ? $"'{string.Join(", ", r.Expected)}' {minimumCount} times, but found {n}"
                                                                : $"'{string.Join(", ", r.Expected)}' between {minimumCount} and {maximumCount} times, but found {n}";

                        return ParserResult <TToken, IEnumerable <T> > .Failure(i, new[] { exp }, msg);
                    }

                    if (!ReferenceEquals(remainder, r.Rest))
                    {
                        result.Add(r.Value);
                    }

                    remainder = r.Rest;
                }

                return ParserResult <TToken, IEnumerable <T> > .Success(remainder, result);
            });
        }
Пример #5
0
        public static Parser <char, char> Char(Func <char, bool> predicate, string expected)
        {
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

            return((i, n) =>
            {
                if (i.AtEnd)
                {
                    return ParserResult <char, char> .Failure(i, new[] { expected }, "Unexpected end of input");
                }

                if (predicate(i.GetCurrent()))
                {
                    return ParserResult <char, char> .Success(i.Advance(), i.GetCurrent());
                }

                return ParserResult <char, char> .Failure(i, new[] { expected }, $"Unexpected '{i.GetCurrent()}'");
            });
        }
Пример #6
0
 /// <summary>
 /// Lift to a parser monad world
 /// </summary>
 /// <param name="v"></param>
 /// <typeparam name="TToken"></typeparam>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public static Parser <TToken, T> Return <TToken, T>(T v)
 => (i, n) => ParserResult <TToken, T> .Success(i, v);