Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse comments with FParsec

Tags:

f#

fparsec

I'm attempting to parse lisp-style comments from an s-expression language with FParsec. I got a bit of help with parsing single-line comments in this previous thread - How to convert an FParsec parser to parse whitespace

While that was resolved, I still need to parse multiline comments. Here's the current code -

/// Read whitespace character as a string.
let spaceAsStr = anyOf whitespaceChars |>> fun chr -> string chr

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

/// Read a multiline comment.
/// TODO: make multiline comments nest.
let multilineComment =
    between
        (pstring openMultilineCommentStr)
        (pstring closeMultilineCommentStr)
        (charsTillString closeMultilineCommentStr true System.Int32.MaxValue)

/// Read whitespace text.
let whitespace =
    lineComment <|>
    multilineComment <|>
    spaceAsStr

/// Skip any white space characters.
let skipWhitespace = skipMany whitespace

/// Skip at least one white space character.
let skipWhitespace1 = skipMany1 whitespace

Unfortunately, the multilineComment parse never succeeds. Since this is a combinator, I can't put breakpoints or analyze why it won't work.

Any ideas why it won't work?

like image 599
Bryan Edds Avatar asked Dec 06 '11 18:12

Bryan Edds


1 Answers

Try changing the bool argument for closeMultilineCommentStr to false

(charsTillString closeMultilineCommentStr false System.Int32.MaxValue)

Otherwise it will skip over the closeMultilineCommentStr string.

To make it work with nested comments

let rec multilineComment o=
    let ign x = charsTillString x false System.Int32.MaxValue
    between
        (pstring openMultilineCommentStr)
        (pstring closeMultilineCommentStr)
        (attempt (ign openMultilineCommentStr >>. multilineComment >>. ign closeMultilineCommentStr) <|> 
        ign closeMultilineCommentStr) <|o
like image 186
Gus Avatar answered Nov 02 '22 22:11

Gus