1
votes

I'm implementing a parser that treats comments as white space with FParsec. It seems like it requires a trivial parser conversion, but I don't yet know how to implement that.

Here's the code I'm trying to get to type-check -

let whitespaceTextChars = " \t\r\n"

/// Read whitespace characters.
let whitespaceText = many (anyOf whitespaceTextChars)

/// Read a line comment.
let lineComment = pchar lineCommentChar >>. restOfLine true

/// Skip any white space characters.
let skipWhitespace = skipMany (lineComment <|> whitespaceText)

/// Skip at least one white space character.
let skipWhitespace1 = skipMany1 (lineComment <|> whitespaceText)

The error is on the second argument of both the <|> operators (over whitespaceText). The errors are -

Error   1   Type mismatch. Expecting a     Parser<string,'a>     but given a     Parser<char list,'a>     The type 'string' does not match the type 'char list'
Error   2   Type mismatch. Expecting a     Parser<string,'a>     but given a     Parser<char list,'a>     The type 'string' does not match the type 'char list'

It seems I need to convert a Parser<char list, 'a> to a Parser<string, 'a>. Or, since I'm just skipping them, I could convert them both to Parser<unit, 'a>. However, I don't know how to write that code. Is it some simple lambda expression?

Cheers!

1
Parsing text as a char list and then converting the list to a string is pretty inefficient. It's better to use one of the parser combinators that directly return strings, see "Parsing strings directly" in quanttec.com/fparsec/reference/parser-overview.html That page also lists some whitespace parsers that you might find helpful. If you didn't yet have a look at the FParsec tutorial, you might find that helpful too: quanttec.com/fparsec/tutorial.html - Stephan Tolksdorf
Some unofficial tutorials helped a little more with understanding "how" to use FParsec. The links you gave are good as reference (especially to see what Parsers are available and how to do certain things). But for some basic parsing examples other tutorials might be easier to understand (especial if you don't know F# well as me ;) ) - Daniel Bişar

1 Answers

2
votes

let whitespaceText = manyChars (anyOf whitespaceTextChars)

or

let whitespaceText = many (anyOf whitespaceTextChars) |>> fun cs -> System.String (Array.ofList cs)