gpt4 book ai didi

f# - FParsec ‘many’ 原语在 stream.UserState 更新时失败

转载 作者:行者123 更新时间:2023-12-04 15:05:47 24 4
gpt4 key购买 nike

以下例程是对 official documentation, "Tracing a parser" 的一个小而简化的更改“解析器跟踪包装器。

let (<!>) (parser: Parser<_,USER_STATE>) label : Parser<_,USER_STATE> =
fun stream ->
do stream.UserState <- stream.UserState // <= works if commented out!
let reply = parser stream
reply

此包装允许检查 reply随着解析器执行和更新 stream.UserState根据需要。

注意:此代码只是复制了 stream.UserState到自己身上,实际上什么都不做,因为这是以下错误的最小操作。 official documentation manipulating stream.UserState ("Recursive grammers with nesting restrictions”)操纵 stream.UserState更多...

注释掉 do stream.UserState <- stream.UserState第 3 行允许重复(生成列表)和非重复 FParsec 原语成功。对于这些生成列表的原语,最后的从属解析器故障被解除并且应用,例如,many成功。

如果parser在上面的包装器中 NOT 是一个 FParsec 原语,它创建一个结果列表(如 manysepEndBy ),从属解析器的重复应用然后这段代码解析成功

如果parser FParsec 重复原语(例如 manysepEndBy ),然后从属解析器应用程序的失败作为重复 FParsec 原语的失败也传回 - 意外失败

为什么包括do stream.UserState <- stream.UserState导致像 many 这样的 FParsec 原语失败?

EDIT1:请注意 FParsec documentation分配给 stream.UserState正如在这个问题中所做的那样。 @brianbern,鉴于文档,我从你的帖子中不明白我在做什么是错误的。谢谢!

如何分配给stream.UserState不中断对 FParsec 的调用 many原始?

最佳答案

发生这种情况的原因是 CharStream.UserState 的 setter 增加了流的 StateTag 作为副作用。来自FParsec source code :

public TUserState UserState {
get { return _UserState; }
set { _UserState = value; ++StateTag; }
}

因此,当您将流的 UserState 分配给它自己时,它等同于什么都不做。

更新:“many”的文档” 解析器状态:

The parser many p repeatedly applies the parser p until p fails. It returns a list of the results returned by p. At the end of the sequence p must fail without changing the parser state and without signalling a FatalError, otherwise many p will fail with the error reported by p.

FParsec 文档中的示例不会在序列末尾修改解析器状态,但您的示例解析器会在每次调用时修改解析器状态。

关于f# - FParsec ‘many’ 原语在 stream.UserState 更新时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66143786/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com