Problems with Forward References in FParsec

68 Views Asked by At

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)?

1

There are 1 best solutions below

2
Martin521 On

Your last line should be

predicateListRef.Value <- sepBy1 predicate comma

You have bound predicateListRef further up in your code to a reference cell, and now you have to set its value.

Related Questions in F#