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