FParsec在可选解析器上失败 [英] FParsec failing on optional parser

查看:42
本文介绍了FParsec在可选解析器上失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在学习FParsec库,但是遇到了一个问题.当我想解析可选字符串并在以后继续正常解析时,FParsec将在可选解析器上返回致命错误,而不是像我期望的那样返回 None .下面的工作代码示例阐明了我的观点:

I am currently learning the FParsec library, but I have come across an issue. When I want to parse an optional string and continue parsing as normal afterwards, FParsec will return a fatal error on the optional parser, rather than returning None as I expect. The below working code sample illustrates my point:

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 返回一个 Default 实体.但是,相反,出现以下错误:

The behavior I would expect is for pOptEntity to return a Default entity when an entity is not provided. However, instead, I get the following error:

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

opt 不能提供我正在描述的行为,并继续正常解析帐户字符串,还是我以不正确的方式处理此问题?我查看了 attempt ,但是,那么,我将无法提供所需的默认实体行为.

Shouldn't opt provide the behavior I am describing and continue to parse the account string as normal or am I approaching this in the incorrect manner? I took a look at attempt but, then, I wouldn't be able to provide the default entity behavior like I want.

非常感谢您的帮助.

推荐答案

< |> 文档,它提到如果第一个解析器失败而未更改解析器状态,则会尝试第二个解析器. http://www.quanttec.com/fparsec/users-guide/parsing-alternatives.html 进行了更详细的介绍.

The 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 goes into more detail.

在这里, ./code>组合器是您要在 pEntity 解析器中使用的.将.>> 替换为.>>?,您将拥有一个 pEntity 解析器,如果不遵循的话通过/进行操作,将回溯到尝试执行的内容,并且不会消耗任何输入.这将允许 opt 组合器按设计运行.

Here, the .>>? combinator is what you want to use in your pEntity parser. Replace the .>> with .>>? and you'll have a pEntity parser that, if it is not followed by a /, will backtrack to the beginning of what it attempted and not consume input. This will allow the opt combinator to function as designed.

PS .我对此进行了测试,并成功了.在 pEntity 中用.>>>?替换.>> ,然后运行您的代码,将产生以下输出:

P.S. I tested this, and it worked. Replacing the .>> with .>>? in pEntity and then running your code produced the following output:

Success: Entity "test"
Success: Default

这篇关于FParsec在可选解析器上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆