我尝试的一切都给了我Incomplete(Size(1)).我现在最好的猜测是:
named!(my_u64(&str) -> u64,
map_res!(recognize!(nom::digit), u64::from_str)
);
Run Code Online (Sandbox Code Playgroud)
测试:
#[cfg(test)]
mod test {
#[test]
fn my_u64() {
assert_eq!(Ok(("", 0)), super::my_u64("0"));
}
}
Run Code Online (Sandbox Code Playgroud)
有时在我的变体(例如添加complete!)中,如果我在最后添加一个字符,我已经能够解析它.
我想得到一个工作解析(最终我希望这将允许我为u64包装类型创建一个解析器)但更大的图片我想了解如何正确地自己构建一个解析器.
至于nom 5.1.1组合解析器的方法从基于宏更改为基于函数,在nom 的作者博客中进行了更广泛的讨论。
随着这一变化,另一个随之而来的变化 -流和完整的解析器现在驻留在不同的模块中,你需要明确地选择你需要的解析类型。大多数情况下,模块名称有明显的区别。
旧的宏被保留,但它们在流模式下严格工作。像CompleteStr或CompleteByteSlice已经消失的类型。
要编写您要求使用新方式的代码,例如像这样(注意character::complete导入中的显式)
因为我花了一些时间来掌握它 - 解析器例如map_res返回 aimpl Fn(I) -> IResult<I, O2, E>这就是为什么有额外的一对括号 - 来调用该闭包。
use std::str;
use nom::{
IResult,
character::complete::{
digit1
},
combinator::{
recognize,
map_res
}
};
fn my_u64(input : &str) -> IResult<&str, u64> {
map_res(recognize(digit1), str::parse)(input)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_my_u64() {
let input = "42";
let num = my_u64(input);
assert_eq!(Ok(("", 42u64)), num);
}
}
Run Code Online (Sandbox Code Playgroud)
Nom 4使部分数据的处理比以前的版本更严格,以更好地支持流解析器和自定义输入类型.
实际上,如果解析器用完输入,它不能告诉大家,它意味着已经用完输入,它会始终返回Err::Incomplete.这可能还包含有关解析器预期输入的确切数据的信息(在您的情况下,至少还有1个字节).
它确定是否可能使用AtEof特征进一步输入.这总是返回false了&str和&[u8],因为它们不提供有关它们是否是完整的还是不任何信息!
诀窍是更改解析器的输入类型,使其明确表示输入始终是完整的 - Nom 为此提供了包装CompleteStr和CompleteByteSlice包装,或者您可以实现自己的输入类型.
因此,为了使您的解析器按预期工作,它需要看起来像这样:
named!(my_u64(CompleteStr) -> u64,
map_res!(recognize!(nom::digit), u64::from_str)
);
Run Code Online (Sandbox Code Playgroud)
你的测试看起来像这样:
#[cfg(test)]
mod test {
#[test]
fn my_u64() {
assert_eq!(Ok((CompleteStr(""), 0)), super::my_u64(CompleteStr("0")));
}
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅Nom 4的公告帖子.
| 归档时间: |
|
| 查看次数: |
857 次 |
| 最近记录: |