[英]FParsec failing on optional parser
I am currently learning the FParsec library, but I have come across an issue.我目前正在学习 FParsec 库,但遇到了一个问题。 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.当我想解析一个可选字符串并在之后继续正常解析时,FParsec 将在可选解析器上返回一个致命错误,而不是像我期望的那样返回
None
。 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
The behavior I would expect is for pOptEntity
to return a Default
entity when an entity is not provided.我期望的行为是
pOptEntity
在未提供实体时返回Default
实体。 However, instead, I get the following error:但是,相反,我收到以下错误:
Failure:
Error in Ln: 1 Col: 8
account:subaccount
^
Expecting: '/'
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?不应该
opt
提供我所描述的行为并继续正常解析帐户字符串,还是我以不正确的方式处理此问题? I took a look at attempt
but, then, I wouldn't be able to provide the default entity behavior like I want.我看了一下
attempt
但是,我将无法提供我想要的默认实体行为。
Your help is much appreciated, thank you.非常感谢您的帮助,谢谢。
The opt
combinator follows the same rules as <|>
; opt
组合器遵循与<|>
相同的规则; 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. http://www.quanttec.com/fparsec/users-guide/parsing-alternatives.html更详细。
Here, the .>>?
在这里,
.>>?
combinator is what you want to use in your pEntity
parser. 组合器是您想要在
pEntity
解析器中使用的。 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.并且您将拥有一个
pEntity
解析器,如果它后面没有跟/
,则会回溯到它尝试的内容的开头并且不消耗输入。 This will allow the opt
combinator to function as designed.这将允许
opt
组合器按设计运行。
PS I tested this, and it worked. PS我对此进行了测试,并且有效。 Replacing the
.>>
with .>>?
将
.>>
替换为.>>?
in pEntity
and then running your code produced the following output:在
pEntity
,然后运行您的代码产生以下输出:
Success: Entity "test"
Success: Default
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.