为什么这两个FParsec片段不同?



我想解析给定的char两次,但只返回该字符的string一次。

例如:

aa    ->    a

我有一些代码可以工作,但也有一些代码不能工作,我不明白为什么。

为什么这些片段不同?

// Works
let parseEscapedQuote (c : char)  =
let q = string c
pstring (q + q) >>% q
// Does not work
let parseEscapedQuote (c : char)  =
let q = string c
pchar c >>. pchar c >>% q

第二个将以您想要的方式成功解析重复字符,但它可能不会以您期望的方式失败。如果只有第一个pchar c成功,它将使解析器处于无效状态。要解决这个问题,您可以使用attempt,它可以在失败时恢复先前的状态:

attempt (pchar c >>. pchar c) >>% q

下面是一个完整的例子,说明了两者的区别:

open FParsec
let parseTwiceBad (c : char) =
pchar c >>. pchar c >>% string c
let parseTwiceGood (c : char) =
attempt (pchar c >>. pchar c) >>% string c
let mkParser parseTwice =
choice [
parseTwice 'x'
anyString 3
]
let run parser str =
let result = runParserOnString parser () "" str
match result with
| Success (value, _, _) -> printfn "Success: %A" value
| Failure (msg, _, _) -> printfn "Failure: %s" msg
let test str =
printfn ""
printfn "Parsing "%s" with bad parser:" str
let parser = mkParser parseTwiceBad
run parser str
printfn "Parsing "%s" with good parser:" str
let parser = mkParser parseTwiceGood
run parser str
[<EntryPoint>]
let main argv =
test "xx"
test "xAx"
0

输出:

Parsing "xx" with bad parser:
Success: "x"
Parsing "xx" with good parser:
Success: "x"
Parsing "xAx" with bad parser:
Failure: Error in Ln: 1 Col: 2
xAx
^
Expecting: 'x'
Parsing "xAx" with good parser:
Success: "xAx"

最新更新