The actual scenario below is made up. The purpose of the question is to understand more about what FParsec is doing here.
I am parsing a list of the strings (w)
and (x)
that are separated by one or more space characters ' '
.
The parser for my list xs
uses sepBy
with a separator parser isSeparator
.
isSeparator
is based on manySatisfy
and seems to correctly consume spaces. I believe this can be seen in the test output below when it parses two leading space characters it ends at position 3.
However, it fails when I use it in xs
, as shown below.
Why does this fail and what would be a good approach for dealing with a separator that could be one or more spaces?
open FParsec
let test p str =
match run p str with
| Success(result, _, p) -> printfn "Success: %A position = %A" result p
| Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
let str s = pstringCI s
let w = str "(w)"
let z = str "(z)"
let woz = w <|> z
let isSeparator = manySatisfy (fun c -> c = ' ')
let xs = sepBy woz isSeparator
test isSeparator " (w)" // Success: " " position = (Ln: 1, Col: 3)
test xs "(z) (w)" // Failure: Error in Ln: 1 Col: 8
// (z) (w)
// ^
// Note: The error occurred at the end of the input stream.
// Expecting: '(w)' (case-insensitive) or '(z)' (case-insensitive)