예제 #1
0
 /// <summary>
 /// Throw exception if EOF reached.
 /// </summary>
 private static void ThowIfEof(this ICharInput input)
 {
     if (input.IsEof())
     {
         throw new ParsingException("unexpected end of file", input.Position);
     }
 }
예제 #2
0
 /// <summary>
 /// Consume leading spaces.
 /// </summary>
 private static ICharInput ConsumeSpaces(this ICharInput input)
 {
     while (char.IsWhiteSpace(input.Current))
     {
         input = input.GetNext();
     }
     return(input);
 }
예제 #3
0
        private static ParseResult <QuotedOrNonquotedValueNode> ParseNonquotedValue(ICharInput input)
        {
            var res = input.ConsumeWhileNonSpace();

            return
                (CreateResult(
                     new QuotedOrNonquotedValueNode(res.Result, input.Position, res.InputRest.Position - input.Position, false),
                     res.InputRest));
        }
예제 #4
0
 private static ICharInput ConsumeChar([NotNull] this ICharInput input, char charToConsume)
 {
     if (input.Current != charToConsume)
     {
         throw new ParsingException(
                   $"'{charToConsume}' expected, but '{input.Current}' found",
                   input.Position);
     }
     return(input.GetNext());
 }
예제 #5
0
 /// <summary>
 /// Consume single char.
 /// </summary>
 private static ICharInput ConsumeChar(this ICharInput input, char charToConsume)
 {
     if (input.Current != charToConsume)
     {
         throw new ParsingException(
                   "'{0}' expected, but '{1}' found".FormatWith(charToConsume, input.Current),
                   input.Position);
     }
     return(input.GetNext());
 }
예제 #6
0
        private static ParseResult <OptionNode> ParseOption(ICharInput input)
        {
            var startPos = input.Position;

            if (!IsOptionPrefix(input.Current))
            {
                throw new ParsingException("invalid option prefix '{0}'");
            }
            input = input.GetNext();

            var name =
                input.ConsumeWhile(
                    c =>
                    c != CharInput.EOF &&
                    !char.IsWhiteSpace(c) &&
                    c != '=' &&
                    c != '+' &&
                    c != '-');

            if (name.Result.Length == 0)
            {
                throw new ParsingException("option name expected", input.Position);
            }

            var nextChar = name.InputRest.Current;

            if (nextChar == '+' || nextChar == '-')
            {
                return
                    (CreateResult(
                         new OptionNode(name.Result, startPos, name.InputRest.Position - startPos + 1, nextChar == '+'),
                         name.InputRest.GetNext()));
            }

            if (nextChar == '=')
            {
                var value = ParseQuotedOrNonquotedValue(name.InputRest.GetNext());
                if (value.Result.Text.Length == 0)
                {
                    throw new ParsingException(
                              "option '{0}' value not specified".FormatWith(name.Result),
                              value.Result.Position);
                }
                return
                    (new ParseResult <OptionNode>(
                         new OptionNode(name.Result, startPos, value.InputRest.Position - startPos, value.Result),
                         value.InputRest));
            }

            return
                (CreateResult(
                     new OptionNode(name.Result, startPos, name.InputRest.Position - startPos),
                     name.InputRest));
        }
예제 #7
0
        /// <summary>
        /// Consume while space character or end of file reached.
        /// </summary>
        private static ParseResult <string> ConsumeWhileNonSpace(this ICharInput input)
        {
            var sb = new StringBuilder();

            while (!input.IsEof() && !char.IsWhiteSpace(input.Current))
            {
                sb.Append(input.Current);
                input = input.GetNext();
            }
            return(new ParseResult <string>(sb.ToString(), input));
        }
예제 #8
0
        private static ParseResult <string> ConsumeWhile([NotNull] this ICharInput input, char stopChar)
        {
            var sb = new StringBuilder();

            while (input.Current != stopChar)
            {
                input.ThowIfEof();
                sb.Append(input.Current);
                input = input.GetNext();
            }
            return(new ParseResult <string>(sb.ToString(), input));
        }
예제 #9
0
        /// <summary>
        /// Consume while predicate is true.
        /// </summary>
        private static ParseResult <string> ConsumeWhile(this ICharInput input, Func <char, bool> predicate)
        {
            var sb = new StringBuilder();

            while (predicate(input.Current))
            {
                input.ThowIfEof();
                sb.Append(input.Current);
                input = input.GetNext();
            }
            return(new ParseResult <string>(sb.ToString(), input));
        }
예제 #10
0
        private static ParseResult <CommandNode> ParseCommand(ICharInput input)
        {
            var res = input.ConsumeWhileNonSpace();

            if (input.IsEof())
            {
                return(null);
            }
            return
                (CreateResult(
                     new CommandNode(res.Result, input.Position, res.InputRest.Position - input.Position),
                     res.InputRest));
        }
예제 #11
0
        private static ParseResult <QuotedOrNonquotedValueNode> ParseQuotedValue(ICharInput input)
        {
            var startPos = input.Position;

            input = input.ConsumeChar(_quota);
            var res = input.ConsumeWhile(_quota);

            input = res.InputRest.ConsumeChar(_quota);
            return
                (CreateResult(
                     new QuotedOrNonquotedValueNode(res.Result, startPos, input.Position - startPos, true),
                     input));
        }
예제 #12
0
        private static ParseResult <CommandOrOption> ParseCommandOrOption(ICharInput input)
        {
            input = input.ConsumeSpaces();
            if (IsOptionPrefix(input.Current))
            {
                var option = ParseOption(input);
                return(new ParseResult <CommandOrOption>(new CommandOrOption(option.Result), option.InputRest));
            }
            var command = ParseCommand(input);

            return
                (command == null
                                        ? null
                                        : new ParseResult <CommandOrOption>(new CommandOrOption(command.Result), command.InputRest));
        }
예제 #13
0
        /// <summary>
        /// Consume many elements.
        /// </summary>
        private static ParseResult <T[]> ConsumeTillEof <T>(
            this ICharInput input,
            Func <ICharInput, ParseResult <T> > consumer)
        {
            var list = new List <T>();

            while (true)
            {
                var res = consumer(input);
                if (res == null)
                {
                    break;
                }
                list.Add(res.Result);
                input = res.InputRest;
            }
            return(new ParseResult <T[]>(list.ToArray(), input));
        }
예제 #14
0
 ///<summary>
 /// Initialize instance with result.
 ///</summary>
 public ParseResult([NotNull] T result, [NotNull] ICharInput inputRest)
 {
     Result    = result;
     InputRest = inputRest;
 }
예제 #15
0
 private static ParseResult <T> CreateResult <T>([NotNull] T result, [NotNull] ICharInput inputRest) =>
 new ParseResult <T>(result, inputRest);
예제 #16
0
 private static ParseResult <T> CreateResult <T>(T result, ICharInput inputRest) =>
 new ParseResult <T>(result, inputRest);
예제 #17
0
 /// <summary>
 /// True, if end of file reached.
 /// </summary>
 private static bool IsEof([NotNull] this ICharInput input) => input.Current == CharInput.Eof;
예제 #18
0
 /// <summary>
 /// True, if end of file reached.
 /// </summary>
 private static bool IsEof(this ICharInput input)
 {
     return(input.Current == CharInput.EOF);
 }
예제 #19
0
 ///<summary>
 /// Initialize instance with result.
 ///</summary>
 public ParseResult(T result, ICharInput inputRest)
 {
     Result    = result;
     InputRest = inputRest;
 }
예제 #20
0
 private static ParseResult <QuotedOrNonquotedValueNode> ParseQuotedOrNonquotedValue(ICharInput input)
 {
     return(input.Current == _quota?ParseQuotedValue(input) : ParseNonquotedValue(input));
 }
예제 #21
0
 private static ParseResult <T> CreateResult <T>(T result, ICharInput inputRest)
 {
     return(new ParseResult <T>(result, inputRest));
 }
예제 #22
0
 private static ParseResult <QuotedOrNonquotedValueNode> ParseQuotedOrNonquotedValue([NotNull] ICharInput input) =>
 input.Current == _quota?ParseQuotedValue(input) : ParseNonquotedValue(input);