提问人:bookofproofs 提问时间:8/21/2023 最后编辑:bookofproofs 更新时间:8/22/2023 访问量:59
FParsec 中的前向引用问题
Problems with Forward References in FParsec
问:
我正在尝试使用 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# 和函数式编程)?
答:
1赞
Martin521
8/22/2023
#1
你的最后一行应该是
predicateListRef.Value <- sepBy1 predicate comma
您已在代码中将 predicateListRef 进一步绑定到引用单元格,现在必须设置其值。
评论
0赞
bookofproofs
8/23/2023
谢谢。同时,我发现了似乎也是另一种解决方案“predicateListRef := sepBy1 谓词逗号”。它在 F# / FParsec 中是等效的还是其他的?
0赞
Martin521
8/24/2023
是的,这仍然有效,但已被弃用。
评论