I want to create a parser for EOL, I can't just do whitespace because I need it to ignore spaces.
So I want to create a parser that will match on "\r\n" or '\n'. Doing a single character is easy Character.EqualTo('\n')
but trying to match a specific string literal is perplexing me. I would think this should be a regular thing that needs to be done for keywords, but I am at a loss.
The \r\n
combination is a string, which means that you need to combine the simple \n
parser (that is a character parser) with a string parser.
How about:
public static void Main()
{
var crlf =
from carriageReturn in Character.EqualTo('\r')
from lineFeed in Character.EqualTo('\n')
select new string(carriageReturn, 1) + lineFeed;
var lf =
from lineFeed in Character.EqualTo('\n')
select new string(lineFeed, 1);
var eol = crlf.Or(lf);
eol.TryParse("\r\n").Dump(); // Successful parsing of \r\n
eol.TryParse("\n").Dump(); // Successful parsing of \n
eol.TryParse("\r").Dump(); // Syntax error: unexpected end of input, expected line feed.
}
If you prefer the non-LINQ syntax:
var eol = Character.EqualTo('\r')
.Then(carriageReturn => Character.EqualTo('\n').Select( lineFeed => new [] {carriageReturn, lineFeed}))
.Or(Character.EqualTo('\n').Select(lineFeed => new[] { lineFeed }));
Edited: Use the Span parser to parse strings:
var eol = Span.EqualTo("\n")
.Or(Span.EqualTo("\r\n"));