用nom解析一个特定大小的数字

  • 本文关键字:数字 一个 nom rust nom
  • 更新时间 :
  • 英文 :


我可以解析这样一个数字:

map_res(digit1, |s: &str| s.parse::<u16>())

但是,只有当一个数字在一定范围内时,我才能解析它?

您可以检查解析的数字是否符合范围,如果不符合,则返回错误:

map_res(digit1, |s: &str| {
// uses std::io::Error for brevity, you'd define your own error
match s.parse::<u16>() {
Ok(n) if n < MIN || n > MAX => Err(io::Error::new(io::ErrorKind::Other, "out of range")),
Ok(n) => Ok(n),
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e.to_string())),
}
})

匹配也可以用and_thenmap_err组合子表示:

map_res(digit1, |s: &str| {
s.parse::<u16>()
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))
.and_then(|n| {
if n < MIN || n > MAX {
Err(io::Error::new(io::ErrorKind::Other, "out of range"))
} else {
Ok(n)
}
})
})

您可以使用验证便利组合子。像这样:

fn parse_u16_clamped(i: &str, min: u16, max: u16) -> IResult<&str, u16> {
let number = map_res(digit1, |s: &str| s.parse::<u16>());
verify(number, |n| n < max && n > min)(i)
}

由于ErrorKind::Other不会出现在Nom 7中,您也可以将context()添加到VerboseError:

fn parse_range<T: FromStr + PartialOrd>(
s: &str,
r: Range<T>,
) -> IResult<&str, T, VerboseError<&str>> {
let (s2, n) = map_res(digit1, |digits: &str| digits.parse::<T>())(s)?;
if !r.contains(&n) {
context("out of range", fail)(s)
} else {
Ok((s2, n))
}
}

相关内容

  • 没有找到相关文章

最新更新