Last active
February 26, 2019 01:00
-
-
Save aaronpowell/ae1d96f3c185dc2a015229526f711bc3 to your computer and use it in GitHub Desktop.
C# parser in F#
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
using System; | |
using System.Collections.Generic; | |
namespace Parser.CSharp | |
{ | |
public static class ParserCSharp | |
{ | |
public static string[] ParseCommandline(string input) | |
{ | |
var items = new List<string>(); | |
var buffer = string.Empty; | |
var hold = false; | |
foreach (var s in input) | |
{ | |
if (s == '"') | |
{ | |
if (hold) | |
{ | |
items.Add(buffer); | |
buffer = string.Empty; | |
hold = false; | |
} | |
else | |
{ | |
hold = true; | |
} | |
continue; | |
} | |
if (s == ' ' && !hold) | |
{ | |
if (buffer != string.Empty) | |
{ | |
items.Add(buffer); | |
} | |
buffer = string.Empty; | |
continue; | |
} | |
buffer += s; | |
} | |
if (buffer != string.Empty) | |
items.Add(buffer); | |
return items.ToArray(); | |
} | |
} | |
} |
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
namespace Parser.FSharp | |
module ParserFSharp = | |
type ParseState = { holding: bool; buffer: string; items: string list } | |
let addBufferToItems state = | |
{state with buffer=""; items=state.buffer :: state.items} | |
let parseChar state = | |
function | |
| '"' when state.holding -> | |
{state with holding=false} |> addBufferToItems | |
| '"' -> | |
{state with holding=true} | |
| ' ' when not state.holding -> | |
if state.buffer = "" then state | |
else addBufferToItems state | |
| c -> | |
{state with buffer=state.buffer + (string c)} | |
let parseCommandline line = | |
let finalState = match (Seq.fold parseChar {holding=false; buffer=""; items = []} line) with | |
| fs when fs.buffer = "" -> fs | |
| fs -> addBufferToItems fs | |
List.rev finalState.items |
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
using System; | |
using System.Collections.Generic; | |
using Parser.CSharp; | |
using Parser.FSharp; | |
using Xunit; | |
namespace Parser.Tests | |
{ | |
class DataSource { | |
private static List<object[]> data = new List<object[]> { | |
new object[] { "help", new[] { "help" } }, | |
new object[] { "help user", new[] { "help", "user" } }, | |
new object[] { "user change-password admin P@55-w0rd!1", new[] { "user", "change-password", "admin", "P@55-w0rd!1" } }, | |
new object[] { "user change-name admin \"Aaron Powell\"", new[] { "user", "change-name", "admin", "Aaron Powell" } } | |
}; | |
public static IEnumerable<object[]> TestData | |
{ | |
get { return data; } | |
} | |
} | |
public class ParserTests | |
{ | |
[Theory] | |
[MemberData(nameof(DataSource.TestData), MemberType = typeof(DataSource))] | |
public void RunTests_CSharp(string key, string[] value) | |
{ | |
var result = ParserCSharp.ParseCommandline(key); | |
Assert.Equal(value, result); | |
} | |
[Theory] | |
[MemberData(nameof(DataSource.TestData), MemberType = typeof(DataSource))] | |
public void RunTests_FSharp(string key, string[] value) | |
{ | |
var result = ParserFSharp.parseCommandline(key); | |
Assert.Equal(value, result); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment