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

F# 为什么这两个FParsec片段不同?,f#,fparsec,F#,Fparsec,我想对给定的char进行两次解析,但只返回该字符的字符串一次 例如: aa -> a 我有一些代码可以工作,但也有一些代码不工作,我不明白为什么 为什么这些片段不同 //有效 让parseEscapedQuote(c:char)= 设q=字符串c pstring(q+q)>>%q //不起作用 让parseEscapedQuote(c:char)= 设q=字符串c pchar c>>。pchar c>>%q 第二个将以您想要的方式成功解析重复字符,但它可能不会以您期望的方式

我想对给定的
char
进行两次解析,但只返回该字符的
字符串一次

例如:

aa    ->    a
我有一些代码可以工作,但也有一些代码不工作,我不明白为什么

为什么这些片段不同

//有效
让parseEscapedQuote(c:char)=
设q=字符串c
pstring(q+q)>>%q
//不起作用
让parseEscapedQuote(c:char)=
设q=字符串c
pchar c>>。pchar c>>%q

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

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

谢谢,这很有道理。我发现回溯
尝试是使用FParsec时最容易出错的部分。是的,这可能会让人困惑<代码>尝试稍微慢一点,但它使您更容易对解析器的行为进行推理。
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"