Last active
January 6, 2018 13:14
-
-
Save shanecelis/55d2d888cf57ab8ef0a3432456953281 to your computer and use it in GitHub Desktop.
A little parser that handles escaping, single-, and double-quotes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Original code Copyright (c) 2018 Shane Celis[1] | |
Licensed under the MIT License[2] | |
Original code posted here[3]. | |
This comment generated by code-cite[4]. | |
[1]: https://github.com/shanecelis | |
[2]: https://opensource.org/licenses/MIT | |
[3]: https://gist.github.com/shanecelis/55d2d888cf57ab8ef0a3432456953281 | |
[4]: https://github.com/shanecelis/code-cite | |
*/ | |
using System.Collections.Generic; | |
using Sprache; | |
/* | |
A little parser that handles escaping, single-, and double-quotes. It's meant | |
to make a quick-and-dirty Command Line Interface (CLI)-like parser. | |
Also shows how one can do monadic parsing in C# using Linq syntax too. | |
Examples of usage: | |
CLILikeParser.ParseString(@"hello world") -> {"hello", "world"} | |
CLILikeParser.ParseString(@"hello\ world") -> {"hello world"} | |
CLILikeParser.ParseString(@"hello 'world'") -> {"hello", "world"} | |
CLILikeParser.ParseString(@"hello 'world thing'") -> {"hello", "world thing"} | |
CLILikeParser.ParseString(@"hello \"world 'thing'\"") -> {"hello", "world 'thing'"} | |
CLILikeParser.ParseString(@"hello 'world \"thing\"') -> {"hello", "world \"thing\""} | |
*/ | |
public static class CLILikeParser { | |
// https://www.thomaslevesque.com/2017/02/23/easy-text-parsing-in-c-with-sprache/ | |
public static readonly Parser<char> escapedChar = | |
from _ in Parse.Char('\\') | |
from c in Parse.AnyChar | |
select c; | |
private static readonly Parser<char> _quotedText = | |
Parse.AnyChar.Except(Parse.Char('\'')); | |
private static readonly Parser<char> _doubleQuotedText = | |
Parse.AnyChar.Except(Parse.Char('"')); | |
public static readonly Parser<string> quotedString = | |
from open in Parse.Char('\'') | |
from text in escapedChar.Or(_quotedText).Many().Text() | |
from close in Parse.Char('\'') | |
select text; | |
public static readonly Parser<string> doubleQuotedString = | |
from open in Parse.Char('"') | |
from text in escapedChar.Or(_doubleQuotedText).Many().Text() | |
from close in Parse.Char('"') | |
select text; | |
public static readonly Parser<string> bareWord = | |
escapedChar.Or(Parse.CharExcept(' ')).AtLeastOnce().Text(); | |
public static readonly Parser<string> argument = | |
from leading in Parse.WhiteSpace.Many() | |
from arg in quotedString.Or(doubleQuotedString).Or(bareWord) | |
select arg; | |
public static readonly Parser<IEnumerable<string>> commandLine = | |
from arguments in argument.Many() | |
from trailing in Parse.WhiteSpace.Many() | |
select arguments; | |
public static IEnumerable<string> ParseString(string cmdLine) { | |
return commandLine.Parse(cmdLine); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment