我正在尝试使用 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 解析器相信没有更多可用数据?