gpt4 book ai didi

parsing - 标称 5 : creating a combinator using another parser multiple times

转载 作者:行者123 更新时间:2023-11-29 08:23:14 25 4
gpt4 key购买 nike

假设我想创建一个多次使用另一个解析器的组合器,例如,解析由两种引号分隔的字符串:

fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
map(
alt((
tuple((tag("'"), f, tag("'"))),
tuple((tag("\""), f, tag("\"")))
)),
|(_, res, _)| res,
)
}

正如预期的那样,此解析器无法编译并出现“使用移动值”错误:

149 |     fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
| - - move occurs because `f` has type `F`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
...
155 | tuple((tag("'"), f, tag("'"))),
| - value moved here
156 | tuple((tag("\""), f, tag("\"")))
| ^ value used here after move

但是,我不能只将 CopyClone 添加到 F 边界:很多解析器,特别是,返回Nom 的内置函数,既不实现Clone 也不实现Copy。我也不能使用 &f 作为 tuple 的参数,因为那样会出现借用检查错误(f 是一个临时本地值,所以不可能返回用它构造的解析器)。

我看到这样做的唯一方法实际上是通过在一系列嵌套的 match 语句中展开它,直接在函数中重新实现 alt 逻辑,但这似乎真的次优。或者我可能遗漏了一些简单的东西,实际上只使用组合器就可以做我想做的事?

我很确定有更好的方法专门编写如上所述的 quoted 组合器,如果有人展示它会很好,但我的问题更笼统 - 如何我编写了重用相同解析器的组合器?

最佳答案

最简单的方法是明确返回闭包:

fn quoted<'a, F: 'a, O, E: ParseError<&'a str>>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, O, E>
where
F: Fn(&'a str) -> IResult<&'a str, O, E>,
{
move |i| {
map(
alt((
tuple((tag("'"), &f, tag("'"))),
tuple((tag("\""), &f, tag("\"")))
)),
|(_, res, _)| res,
)(i)
}
}

现在,由于 move 关键字,f 值被移动到闭包中。然后,在返回的闭包内,我直接调用复杂的解析器组合器,闭包除了输出/错误之外没有返回任何内容,这意味着我可以自由使用对 f 的引用。

关于parsing - 标称 5 : creating a combinator using another parser multiple times,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56846090/

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