public override string ToString() { if (_chars.Any(x => x.IsEscapeSymbol && !x.IsEscaped)) { PositionedChar unescaped = _chars.First(x => x.IsEscapeSymbol && !x.IsEscaped); throw new UnescapedCharacterException(unescaped); } return(new string(_chars.Select(x => x.Value).ToArray())); }
public static PositionedChar Escape(PositionedChar c) { if (c.Value != '\'' && c.Value != '"' && c.Value != '\\') { throw new UnescapedCharacterException($"Failed to escape character '{c.Value}' and position {c.Index}. " + "Escaping is possible only for single/double quotes and backslash, other escaped " + "characters are not supported."); } return(new PositionedChar(c.Index, c.Value, true)); }
private static IEnumerable <StringToken> GetStringTokensInternal(string s) { if (s == null) { throw new ArgumentNullException(nameof(s)); } PositionedChar[] chars = PositionedChar.GetFromString(s); PositionedCharStringList currentString = new PositionedCharStringList(); int start = int.MinValue; const char singleQuote = '\''; const char doubleQuote = '"'; char openQuote = char.MinValue; for (int i = 0; i < chars.Length; i++) { PositionedChar c = chars[i]; if (start >= 0) { if (c.Value == openQuote && !currentString.IsLastEscapeSymbol) { string value = currentString.ToString(); currentString = new PositionedCharStringList(); openQuote = char.MinValue; yield return(new StringToken(start, i, value)); start = int.MinValue; } else { currentString.Add(c); } } else if (c.Value == singleQuote) { start = i; openQuote = singleQuote; } else if (c.Value == doubleQuote) { start = i; openQuote = doubleQuote; } } if (start != int.MinValue) { throw new UnclosedStringException(openQuote, start); } }
public static PositionedChar[] GetFromString(string s) { if (s is null) { throw new ArgumentNullException(nameof(s)); } PositionedChar[] ret = new PositionedChar[s.Length]; for (int i = 0; i < ret.Length; i++) { ret[i] = new PositionedChar(i, s[i]); } return(ret); }
public void Add(PositionedChar c) { if (_chars.Any()) { PositionedChar last = _chars.Last(); if (last.IsEscapeSymbol && !last.IsEscaped) { PositionedChar escaped = PositionedChar.Escape(c); _chars.Remove(last); _chars.Add(escaped); } else { _chars.Add(c); } } else { _chars.Add(c); } }
private static bool TryReadNumberToken(PositionedChar[] chars, ref int index, out NumberToken token) { int startIndex = index; List <PositionedChar> tokenChars = new List <PositionedChar>(); bool read; char c; do { c = chars[index].Value; read = char.IsDigit(c) || c == '.'; if (read) { tokenChars.Add(chars[index]); index++; } }while (read && index < chars.Length); if (!tokenChars.Any() || (tokenChars.Count == 1 && tokenChars[0].Value == '.')) { index = startIndex; token = null; return(false); } string readString = PositionedChar.CreateString(tokenChars); if (double.TryParse(readString, NumberToken.AllowedStyle, CultureInfo.InvariantCulture, out double d)) { token = new NumberToken(chars[startIndex].Index, chars[index - 1].Index, d); return(true); } index = startIndex; token = null; return(false); }
internal SymbolToken(PositionedChar c) : this(c.Index, c.Value) { }
private static bool TryReadPropertyToken(PositionedChar[] chars, ref int index, out PropertyToken token) { int startIndex = index; bool read; char c; List <PositionedChar> currentValue = new List <PositionedChar>(); do { c = chars[index].Value; read = char.IsLetter(c) || c == '$' || c == '_'; if (!read && currentValue.Any() && char.IsDigit(c)) { read = true; } if (read) { currentValue.Add(chars[index]); index++; } }while (read && index < chars.Length); if (currentValue.Any()) { token = new PropertyToken(chars[startIndex].Index, chars[index - 1].Index, PositionedChar.CreateString(currentValue), false); return(true); } token = null; index = startIndex; return(false); }