We left off with a working solution for parsing either “po/k”, “x4/0”, and “s12” into our choice type of Operation. We can always go back and look at our original solution here. We really want to be able to parse a bunch of operations separated by a comma.
Parsing Many
When we want to parse a large blob of operations separated by a comma we can use the sepBy function.
sepBy : Parser<‘a, ‘u> -> Parser<‘b, ‘u> -> Parser<‘a list, ‘u> We can see by the function signature, it takes two parsers as arguments. The first parser determines the result. The second parser determines the separator. Our operations are separated by a comma so we’ll use pchar ‘,’ parser. Let’s combine the sepBy with our previous function parseOperation and can now parse an entire blob of operations.
"po/k,x4/0,s12,x7/6" |> run (sepBy parseOperation (pchar ','))
Alternative or Choice
Revisiting the parserOperation function of
let parseOperation = pspin <|> pexchange <|> ppartner
we could have used the choice : seq> -> Parser<‘a,‘u> function. choice takes a collection of parsers and evaluates them in order to find a match. This can help with readability when having multiple alternative parsers. Instead of weaving the <|> operator between them. We can re-write our function as:
let parseOperation = choice [ pspin; pexchange; ppartner ]
Summary
We’ve replaced our alternative operator <|> with the choice function for readability. We’ve also introduced the sepBy function to parse a block of comma separated operations. The simplest way to test our parsers is by using the run function as it does not require or use any state.