gpt4 book ai didi

rust - 使用 nom 5.0 解析数字

转载 作者:行者123 更新时间:2023-11-29 08:19:51 28 4
gpt4 key购买 nike

我正在尝试使用 Nom 5.0 解析一个大文件(数十 GB)流式传输。解析器的一部分尝试解析数字:

use nom::IResult;
use nom::character::streaming::{char, digit1};
// use nom::character::complete::{char, digit1};
use nom::combinator::{map, opt};
use nom::multi::many1;
use nom::sequence::{preceded, tuple};

pub fn number(input: &str) -> IResult<&str, &str> {
map(
tuple((
opt(char('-')),
many1(digit1),
opt(preceded(char('.'), many1(digit1)))
)),
|_| "0"
)(input)
}

(显然,它不应该为所有数字返回“0”;这只是为了使函数尽可能简单。)对于这个解析器,我写了一个测试:

#[test]
fn match_positive_integer() {
let (_, res) = number("0").unwrap();
assert_eq!("0", res);
}

此测试因 Incomplete(Size(1)) 而失败,因为“小数”opt() 想要读取数据,但它不存在。如果我切换到匹配器的 complete 版本(如注释掉的行),则测试通过。

我认为这实际上会在生产中起作用,因为当提示不完整时它会被提供额外的数据,但我仍然想创建单元测试。此外,如果一个数字恰好是文件中输入的最后一位,那么在生产中就会出现这个问题。我如何说服流式 Nom 解析器没有更多可用数据?

最佳答案

可以说测试的原始形式是正确的:解析器无法确定给定的输入是否为数字,因此解析结果实际上尚未确定。在生产中,尤其是像您一样读取大文件时,已读取但待解析字节的缓冲区可能恰好在可能 之间结束,除非它实际上不是。然后,解析器需要保留其当前状态并请求更多输入以便重试/继续。 Incomplete 不是最终错误,而是我什至不知道:这可能是一个错误,具体取决于下一个字节,这个问题目前还无法确定! .

您可以使用 complete-combinator 在你的顶级解析器上 所以当你实际上到达 EOF 时,你就错了。 不完整-results within 顶级解析器应该被处理,例如通过将读取缓冲区扩大一些余量并重试。

您可以将解析器包装在 complete() 中 - 当前单元测试的本地解析器并对其进行测试。一些符合的调子

#[test]
fn match_positive_integer() {
let (_, res) = complete(number("0")).unwrap();
assert_eq!("0", res);
}

关于rust - 使用 nom 5.0 解析数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57914504/

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