I'm trying to write a Parser with FParsec to parse nested boolean expressions, for instance:
false
true
and(false,true,true,true,true)
or(true,true)
and(or(false,true),and(true,true,true,true))
Because my grammar involves mutually recursive definitions, I read in this article that I need createParserForwardedToRef
My problem is that once I do it, the F# compiler generates the error Error FS0037: Duplicate definition of value 'predicateListRef'
This is a working example to reproduce the error:
open FParsec
type Predicate =
| True
| False
| And of Predicate list
| Or of Predicate list
let leftParen: Parser<_, unit> = skipChar '('
let rightParen: Parser<_, unit> = skipChar ')'
let comma: Parser<_, unit> = skipChar ','
let keywordTrue: Parser<_,unit> = skipString "true" >>% Predicate.True
let keywordFalse: Parser<_,unit> = skipString "false" >>% Predicate.False
let keywordAnd: Parser<_,unit> = skipString "and"
let keywordOr: Parser<_,unit> = skipString "or"
////// resolving recursive parsers
let predicateList, predicateListRef = createParserForwardedToRef()
let primePredicate = choice [
keywordTrue
keywordFalse
]
let conjunction = (keywordAnd >>. leftParen >>. predicateList) .>> rightParen |>> Predicate.And
let disjunction = (keywordOr >>. leftParen >>. predicateList) .>> rightParen |>> Predicate.Or
let compoundPredicate = choice [
conjunction
disjunction
]
let predicate = choice [
primePredicate
compoundPredicate
]
let predicateListRef = sepBy1 predicate comma // the error occurs at this line
What am I doing wrong (sorry, I'm not familiar with FParsec, F#, and functional programming)?
Your last line should be
You have bound predicateListRef further up in your code to a reference cell, and now you have to set its value.