/// <summary> /// Emits a token into the output stream. /// </summary> /// <param name="output">The output stream into which to emit the token.</param> /// <param name="token">The token to emit into the output stream.</param> /// <param name="lineIndex">The current line index.</param> /// <param name="columnIndex">The current column index.</param> /// <param name="options">The lexer's configurable options.</param> /// <returns>The number of characters by which to advance the lexer's position /// within the source string.</returns> private static Int32 EmitToken(IList <UvssLexerToken> output, UvssLexerToken token, ref Int32 lineIndex, ref Int32 columnIndex, UvssLexerOptions options) { HandleLineAndColumnTracking(token.Text, ref lineIndex, ref columnIndex, options); output.Add(token); return(token.Text.Length); }
/// <summary> /// Tokenizes the specified Ultraviolet StyleSheets (UVSS) string. /// </summary> /// <param name="source">The source string to tokenize.</param> /// <param name="options">The lexer's configurable options, or null to use the default options.</param> /// <returns>A <see cref="UvssLexerStream"/> instance which produces lexed tokens from the specified source text.</returns> public static UvssLexerStream Tokenize(String source, UvssLexerOptions options = null) { Contract.Require(source, nameof(source)); var instance = new UvssLexer(source, options ?? UvssLexerOptions.Default); return(new UvssLexerStream(instance)); }
/// <summary> /// Calculates the length of the specified token text in columns, performing tab expansion if necessary. /// </summary> /// <param name="text">The text of the token that is being emitted.</param> /// <param name="offset">The offset into the token text at which to begin measuring length.</param> /// <param name="options">The lexer's configurable options.</param> /// <returns>The length of the specified token text in columns.</returns> private static Int32 CalculateTokenLengthInColumns(String text, Int32 offset, UvssLexerOptions options) { var length = 0; for (int i = offset; i < text.Length; i++) { length += (text[i] == '\t') ? options.TabSize : 1; } return(length); }
/// <summary> /// Determines whether the lexer has advanced to a new line and updates the line index accordingly. /// In addition, this method moves the column index forward by the length of the current token, /// performing tab expansion as necessary. /// </summary> /// <param name="text">The text of the token that is being emitted.</param> /// <param name="lineIndex">The current line index.</param> /// <param name="columnIndex">The current column index.</param> /// <param name="options">The lexer's configurable options.</param> private static void HandleLineAndColumnTracking(String text, ref Int32 lineIndex, ref Int32 columnIndex, UvssLexerOptions options) { var newlineMatches = regexNewline.Matches(text); if (newlineMatches.Count > 0) { var lineStartOffset = 0; foreach (Match match in newlineMatches) { lineIndex++; lineStartOffset = match.Index + match.Length; } columnIndex = 1 + CalculateTokenLengthInColumns(text, lineStartOffset, options); } else { columnIndex += CalculateTokenLengthInColumns(text, 0, options); } }
/// <summary> /// Initializes a new instance of the <see cref="UvssLexer"/> class. /// </summary> /// <param name="source">The source which is being lexed.</param> /// <param name="options">The lexer's options.</param> private UvssLexer(String source, UvssLexerOptions options) { this.source = source; this.options = options; }