FParsec 在可选解析器上失败

FParsec failing on optional parser

我目前正在学习 FParsec 库,但遇到了一个问题。当我想解析一个可选字符串并在之后继续正常解析时,FParsec 将 return 可选解析器上的致命错误,而不是我预期的 returning None。下面的工作代码示例说明了我的观点:

open System
open FParsec

type AccountEntity = 
    | Default 
    | Entity of string

let pEntity =
    let isEntityFirstChar c = isLetter c
    let isEntityChar c = isLetter c || isDigit c
    (many1Satisfy2L isEntityFirstChar isEntityChar "entity") .>> skipString "/"

let pOptEntity =
     opt pEntity
     |>> (fun optEntity -> 
              match optEntity with 
              | Some entity -> Entity entity 
              | None -> Default)

[<EntryPoint>]
let main argv = 
    printfn "%A" (run pOptEntity "test/account:subaccount") //works
    printfn "%A" (run pOptEntity "account:subaccount") //crashes
    Console.ReadLine() |> ignore
    0 // return an integer exit code

我期望的行为是 pOptEntity 到 return 未提供实体时的 Default 实体。但是,相反,我收到以下错误:

Failure:
Error in Ln: 1 Col: 8
account:subaccount
       ^
Expecting: '/'

不应该 opt 提供我正在描述的行为并继续正常解析帐户字符串,还是我以不正确的方式处理这个问题?我查看了 attempt 但是,我无法提供我想要的默认实体行为。

非常感谢您的帮助,谢谢。

opt combinator follows the same rules as <|>; if you look at the <|> documentation, it mentions that if the first parser fails without changing the parser state, the second parser is attempted. http://www.quanttec.com/fparsec/users-guide/parsing-alternatives.html 更详细。

此处,.>>? combinator 是您要在 pEntity 解析器中使用的内容。将 .>> 替换为 .>>? 并且您将拥有一个 pEntity 解析器,如果它后面没有 /,将 回溯到开头它尝试的内容 并且不消耗输入。这将使 opt 组合器按设计运行。

P.S. 我测试了这个,它起作用了。将 .>> 替换为 pEntity 中的 .>>? 然后 运行 您的代码产生了以下输出:

Success: Entity "test"
Success: Default