using System.Collections.Generic;
public static void Main()
var stringParser = BuildStringLiteralParser('\"').Or(BuildStringLiteralParser('\''));
var str1 = stringParser.Parse("\"'Hello' \\\"John\\\"\"");
var str2 = stringParser.Parse("\'\\'Hello\\' \"John\"\'");
private static readonly StringBuilder _reusableStringBuilder = new StringBuilder();
private static Parser<string> BuildStringLiteralParser(char delimiterChar)
var delimiter = Sprache.Parse.Char(delimiterChar);
var escape = Sprache.Parse.Char(escapeChar);
var escapedDelimiter = Sprache.Parse.String($"{escapeChar}{delimiterChar}");
var splitByEscape = Sprache.Parse.AnyChar.Except(delimiter.Or(escape)).Many().Text().DelimitedBy(escapedDelimiter);
string BuildStr(IEnumerable<IEnumerable<string>> splittedByEscape)
_reusableStringBuilder.Clear();
foreach (var splittedByEscapedDelimiter in splittedByEscape)
_reusableStringBuilder.Append(escapeChar);
foreach (var str in splittedByEscapedDelimiter)
_reusableStringBuilder.Append(delimiterChar);
_reusableStringBuilder.Append(str);
return _reusableStringBuilder.ToString();
from splittedByEscape in splitByEscape.DelimitedBy(escape)from rn in delimiter
select BuildStr(splittedByEscape)).Named("string");