【发布时间】:2021-02-10 19:32:43
【问题描述】:
以下例程是对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 更多...
在第 3 行注释掉 do stream.UserState <- stream.UserState 允许重复(生成列表)和非重复 FParsec 原语成功。对于这些生成列表的原语,最后一个从属解析器故障被解除,例如 many 的应用程序成功。
如果上述包装器中的parser 不是一个 FParsec 原语,它通过重复应用从属解析器来创建结果列表(如 many 或 sepEndBy) 那么这段代码解析成功。
如果parser IS 是一个 FParsec 重复原语(例如 many 或 sepEndBy),则从属解析器应用程序的失败也将作为重复 FParsec 的失败传递出去原始 - 意外失败。
为什么包含 do stream.UserState <- stream.UserState 会导致像 many 这样的 FParsec 原语失败?
EDIT1:请注意,FParsec documentation 对 stream.UserState 进行了分配,正如在此问题中所做的那样。 @brianbern,我从你的帖子中不明白我在做什么是错误的给定文档。谢谢!
如何在不中断对 FParsec many 原语的调用的情况下分配给stream.UserState?
【问题讨论】: