I am trying to use FParsec to parse a list of zero or more elements of the form [string] where the string in the middle can be anything (except ] as to disambiguate from the end of the string). Here is my code as is:
let parseArgumentList : Parser<string list, unit> =
let parseArgument = (skipChar '[') >>. (manySatisfy (fun x -> x <> ']')) .>> (skipChar ']')
sepBy (parseArgument) (spaces)
[<EntryPoint>]
let main argv =
let parserResult = run parseArgumentList "[testString] [testString]"
printfn "%A" parserResult
0
The output here is:
Failure:
Error in Ln: 1 Col: 26
[testString] [testString]
^
Note: The error occurred at the end of the input stream.
Expecting: '['
It is as if the parser is expecting another set of parenthesis rather than terminating at 2 occurances in sepBy. I tested this by changing the spaces to (skipChar ' ') >>. spaces and sure enough it parses fine. I am however unwilling to remove the option of no spaces between arguments. Any ideas or advice would be greatly appreciated.
CodePudding user response:
I think using sepEndBy instead of sepBy will do what you want:
let parseArgumentList =
sepEndBy parseArgument spaces
From the FParser doc: The parser sepEndBy p sep parses zero or more occurrences of p separated and optionally ended by sep. (Emphasis added.)
Running this on your test input produces the expected result:
Success: ["testString"; "testString"]
Note that this solution also has the nice side-benefit of consuming trailing spaces, if there are any. E.g. When the input is "[testString] [testString] ".
