简体   繁体   中英

FParsec failing at the end of a spaces separated list, expecting another element of the list

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 (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.

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. Eg When the input is "[testString] [testString] " .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM