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)); }
private static void EatWhitespace(TextBuffer buffer) { while (!buffer.ReachedEnd) { var character = buffer.Peek(); if (!char.IsWhiteSpace(character)) { break; } buffer.Read(); } }
private static int ParseToken(CommandTreeTokenizerContext context, TextBuffer reader, int position, int start, List <CommandTreeToken> tokens) { while (reader.Peek() != -1) { if (reader.ReachedEnd) { position += reader.Position - start; break; } var character = reader.Peek(); // Eat whitespace if (char.IsWhiteSpace(character)) { reader.Consume(); continue; } if (character == '-') { // Option tokens.AddRange(ScanOptions(context, reader)); } else { // Command or argument tokens.Add(ScanString(context, reader)); } // Flush remaining tokens context.FlushRemaining(); } return(position); }
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 CommandParseException.InvalidShortOptionName(reader.Original, token); } } if (result.Count > 1) { foreach (var item in result) { item.IsGrouped = true; } } return(result); }
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()); }
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 CommandTemplateException.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}]")); }
private static CommandTreeToken ScanQuotedString(CommandTreeTokenizerContext context, TextBuffer reader) { var position = reader.Position; context.FlushRemaining(); reader.Consume('\"'); var builder = new StringBuilder(); var terminated = false; while (!reader.ReachedEnd) { var character = reader.Peek(); if (character == '\"') { terminated = true; reader.Read(); break; } builder.Append(reader.Read()); } if (!terminated) { var unterminatedQuote = builder.ToString(); var token = new CommandTreeToken(CommandTreeToken.Kind.String, position, unterminatedQuote, $"\"{unterminatedQuote}"); throw CommandParseException.UnterminatedQuote(reader.Original, token); } var quotedString = builder.ToString(); // Add to the context context.AddRemaining(quotedString); return(new CommandTreeToken( CommandTreeToken.Kind.String, position, quotedString, quotedString)); }