public static SqlTemplate Parse(string input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } var reader = new CharSequenceReader(input); bool parsingParameter = false; var template = new SqlTemplate(); template.RawString = input; var ls = new List <SqlTemplateSegment>(); var segmentBuilder = new StringBuilder(); while (reader.HasNext()) { reader.Next(); if (reader.Current() == '@' && !parsingParameter) { if (segmentBuilder.Length != 0) { ls.Add(new SqlTemplateSegment(segmentBuilder.ToString(), false)); segmentBuilder.Clear(); } parsingParameter = true; } else if (parsingParameter && (reader.Current() == ' ' || reader.Current() == '\r' || reader.Current() == '\n' || reader.Current() == '\t')) { bool followIn = ls.Count == 0 ? false : ls[ls.Count - 1].Value.ToLower().Trim().EndsWith(" in") ? true : false; ls.Add(new SqlTemplateSegment(segmentBuilder.ToString(), true, followIn)); segmentBuilder.Clear(); parsingParameter = false; } else { segmentBuilder.Append(reader.Current()); } } if (segmentBuilder.Length != 0) { if (parsingParameter) { bool followIn = ls.Count == 0 ? false : ls[ls.Count - 1].Value.ToLower().Trim().EndsWith(" in") ? true : false; ls.Add(new SqlTemplateSegment(segmentBuilder.ToString(), true, followIn)); } else { ls.Add(new SqlTemplateSegment(segmentBuilder.ToString(), false)); } } template.Segments = ls.ToArray(); return(template); }