コード例 #1
0
        private static CommandTreeToken ScanQuotedString(CommandTreeTokenizerContext context, TextBuffer reader)
        {
            var position = reader.Position;

            reader.Consume('\"');
            context.AddRemaining('\"');

            var builder = new StringBuilder();

            while (!reader.ReachedEnd)
            {
                var character = reader.Peek();
                if (character == '\"')
                {
                    break;
                }

                context.AddRemaining(character);
                builder.Append(reader.Read());
            }

            if (reader.Peek() != '\"')
            {
                var unterminatedQuote = builder.ToString();
                var token             = new CommandTreeToken(CommandTreeToken.Kind.String, position, unterminatedQuote, $"\"{unterminatedQuote}");
                throw ParseException.UnterminatedQuote(reader.Original, token);
            }

            reader.Read();
            context.AddRemaining('\"');

            var value = builder.ToString();

            return(new CommandTreeToken(CommandTreeToken.Kind.String, position, value, $"\"{value}\""));
        }
コード例 #2
0
        private static CommandTreeToken ScanString(
            CommandTreeTokenizerContext context,
            TextBuffer reader,
            char[]?stop = null)
        {
            if (reader.TryPeek(out var character))
            {
                // Is this a quoted string?
                if (character == '\"')
                {
                    return(ScanQuotedString(context, reader));
                }
            }

            var position = reader.Position;
            var builder  = new StringBuilder();

            while (!reader.ReachedEnd)
            {
                var current = reader.Peek();
                if (stop?.Contains(current) ?? false)
                {
                    break;
                }

                reader.Read(); // Consume
                context.AddRemaining(current);
                builder.Append(current);
            }

            var value = builder.ToString();

            return(new CommandTreeToken(CommandTreeToken.Kind.String, position, value.Trim(), value));
        }
コード例 #3
0
        private static void EatWhitespace(TextBuffer buffer)
        {
            while (!buffer.ReachedEnd)
            {
                var character = buffer.Peek();
                if (!char.IsWhiteSpace(character))
                {
                    break;
                }

                buffer.Read();
            }
        }
コード例 #4
0
        private static IEnumerable <CommandTreeToken> ScanOptions(CommandTreeTokenizerContext context, TextBuffer reader)
        {
            var result = new List <CommandTreeToken>();

            var position = reader.Position;

            reader.Consume('-');
            context.AddRemaining('-');

            if (!reader.TryPeek(out var character))
            {
                var token = new CommandTreeToken(CommandTreeToken.Kind.ShortOption, position, "-", "-");
                throw ParseException.OptionHasNoName(reader.Original, token);
            }

            switch (character)
            {
            case '-':
                var option = ScanLongOption(context, reader, position);
                if (option != null)
                {
                    result.Add(option);
                }

                break;

            default:
                result.AddRange(ScanShortOptions(context, reader, position));
                break;
            }

            if (reader.TryPeek(out character))
            {
                // Encountered a separator?
                if (character == '=' || character == ':')
                {
                    reader.Read(); // Consume
                    context.AddRemaining(character);

                    if (!reader.TryPeek(out _))
                    {
                        var token = new CommandTreeToken(CommandTreeToken.Kind.String, reader.Position, "=", "=");
                        throw ParseException.OptionValueWasExpected(reader.Original, token);
                    }

                    result.Add(ScanString(context, reader));
                }
            }

            return(result);
        }
コード例 #5
0
        private static IEnumerable <CommandTreeToken> ScanShortOptions(CommandTreeTokenizerContext context, TextBuffer reader, int position)
        {
            var result = new List <CommandTreeToken>();

            while (!reader.ReachedEnd)
            {
                var current = reader.Peek();
                if (char.IsWhiteSpace(current))
                {
                    break;
                }

                // Encountered a separator?
                if (current == '=' || current == ':')
                {
                    break;
                }

                if (char.IsLetter(current))
                {
                    context.AddRemaining(current);
                    reader.Read(); // Consume

                    var value = current.ToString(CultureInfo.InvariantCulture);
                    result.Add(result.Count == 0
                        ? new CommandTreeToken(CommandTreeToken.Kind.ShortOption, position, value, $"-{value}")
                        : new CommandTreeToken(CommandTreeToken.Kind.ShortOption, position + result.Count, value, value));
                }
                else
                {
                    // Create a token representing the short option.
                    var tokenPosition = position + 1 + result.Count;
                    var represntation = current.ToString(CultureInfo.InvariantCulture);
                    var token         = new CommandTreeToken(CommandTreeToken.Kind.ShortOption, tokenPosition, represntation, represntation);
                    throw ParseException.InvalidShortOptionName(reader.Original, token);
                }
            }

            if (result.Count > 1)
            {
                foreach (var item in result)
                {
                    item.IsGrouped = true;
                }
            }

            return(result);
        }
コード例 #6
0
        private static string ReadOptionName(TextBuffer buffer)
        {
            var builder = new StringBuilder();

            while (!buffer.ReachedEnd)
            {
                var character = buffer.Peek();
                if (char.IsWhiteSpace(character) || character == '|')
                {
                    break;
                }

                builder.Append(buffer.Read());
            }

            return(builder.ToString());
        }
コード例 #7
0
        private static TemplateToken ReadValue(TextBuffer buffer, bool required)
        {
            var start = required ? '<' : '[';
            var end   = required ? '>' : ']';

            var position = buffer.Position;
            var kind     = required ? TemplateToken.Kind.RequiredValue : TemplateToken.Kind.OptionalValue;

            // Consume start of value character (< or [).
            buffer.Consume(start);

            var builder = new StringBuilder();

            while (!buffer.ReachedEnd)
            {
                var character = buffer.Peek();
                if (character == end)
                {
                    break;
                }

                buffer.Read();
                builder.Append(character);
            }

            if (buffer.ReachedEnd)
            {
                var name  = builder.ToString();
                var token = new TemplateToken(kind, position, name, $"{start}{name}");
                throw TemplateException.UnterminatedValueName(buffer.Original, token);
            }

            // Consume end of value character (> or ]).
            buffer.Consume(end);

            // Get the value (the text within the brackets).
            var value = builder.ToString();

            // Create a token and return it.
            return(new TemplateToken(kind, position, value, required ? $"<{value}>" : $"[{value}]"));
        }