我正在尝试用 FParsec 编写一个解析器来解析嵌套的布尔表达式,例如:
false
true
and(false,true,true,true,true)
or(true,true)
and(or(false,true),and(true,true,true,true))
因为我的语法涉及相互递归的定义,所以我在这篇文章中读到我需要
createParserForwardedToRef
我的问题是,一旦我这样做,F#编译器就会生成错误
Error FS0037: Duplicate definition of value 'predicateListRef'
这是重现错误的工作示例:
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
我做错了什么(抱歉,我不熟悉 FParsec、F# 和函数式编程)?
你的最后一行应该是
predicateListRef.Value <- sepBy1 predicate comma
您已在代码中进一步将 predicateListRef 定义为引用单元格,现在您必须设置其值。