FParsec 中的前向引用问题

问题描述 投票:0回答:1

我正在尝试用 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# 和函数式编程)?

reference f# forward fparsec
1个回答
0
投票

你的最后一行应该是

predicateListRef.Value <- sepBy1 predicate comma

您已在代码中进一步将 predicateListRef 定义为引用单元格,现在您必须设置其值。

© www.soinside.com 2019 - 2024. All rights reserved.