gpt4 book ai didi

f# - fparsec - 限制应用解析器的字符数

转载 作者:行者123 更新时间:2023-12-02 16:01:24 24 4
gpt4 key购买 nike

我遇到一个问题,在流的解析过程中,我通过多次(按顺序)应用特定的解析器来指出需要解析下 N 个字符的位置。

(剥离玩具)示例:

17<tag><anothertag><a42...
^
|- I'm here

假设 17 表示接下来的 N=17 个字符组成标签,所以我需要重复应用我的“tagParser”但在 17 个字符后停止并且不消耗其余部分,即使它看起来像标签,因为它有不同的含义,将被另一个解析器解析。

我不能使用 manymany1 因为那会吃掉超过 N 个字符的流。我也不能使用parray,因为我不知道N个字符内有多少个解析器成功应用。

我正在研究 manyMinMaxSatisfy 但无法弄清楚在这种情况下如何使用它。

有没有办法从流中剪切 N 个字符并将它们提供给某个解析器?或者有没有办法调用许多应用程序但最多 N 个字符?

谢谢。

最佳答案

您可以使用 getPosition 来确保您没有超过指定的字符数。我把它放在一起(使用 F# 6),它似乎可以工作,尽管可能有更简单/更快的解决方案:

let manyLimit nChars p =
parse {
let! startPos = getPosition

let rec loop values =
parse {
let! curPos = getPosition
let nRemain = (startPos.Index + nChars) - curPos.Index
if nRemain = 0 then
return values
elif nRemain > 0 then
let! value = p
return! loop (value :: values)
else
return! fail $"limit exceeded by {-nRemain} chars"
}

let! values = loop []
return values |> List.rev
}

测试代码:

let ptag =
between
(skipChar '<')
(skipChar '>')
(manySatisfy (fun c -> c <> '>'))

let parser =
parse {
let! nChars = pint64
let! tags = manyLimit nChars ptag
let! rest = restOfLine true
return tags, rest
}

run parser "17<tag><anothertag><a42..."
|> printfn "%A"

输出是:

Success: (["tag"; "anothertag"], "<a42...")

关于f# - fparsec - 限制应用解析器的字符数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70568689/

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