首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用nom5.0进行解析

用nom5.0进行解析
EN

Stack Overflow用户
提问于 2019-09-12 21:05:59
回答 1查看 754关注 0票数 2

我正在尝试使用nom5.0解析一个大文件(数十GB)流。解析器的一部分试图解析数字:

代码语言:javascript
复制
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“;这只是为了使函数尽可能简单。)对于这个解析器,我编写了一个测试:

代码语言:javascript
复制
#[test]
fn match_positive_integer() {
    let (_, res) = number("0").unwrap();
    assert_eq!("0", res);
}

这个测试在Incomplete(Size(1))中失败了,因为“小数”opt()想要读取数据,但它并不存在。如果我切换到matchers的complete版本(如注释行),测试就会通过。

我认为这实际上会在生产中起作用,因为当抱怨不完整时,它会被输入额外的数据,但是我仍然希望创建单元测试。此外,如果某个数字恰好是文件中的最后一个输入,则该问题将发生在生产过程中。我如何使流no解析器相信没有更多的数据可用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-16 18:38:55

可以说,测试的原始形式是正确的:解析器无法确定给定的输入是否为数字,因此解析结果实际上尚未确定。在生产中,特别是在像您这样读取大型文件时,已经读取但将被解析的字节的缓冲区可能在数字之间结束,除非它实际上不是。然后,解析器需要保留其当前状态,并请求更多的输入,以便可以重试/继续。不要把Incomplete看作是一个最终的错误,而是把它看作是I don't even know: This could be an error depending on the next byte, this problem is undecidable as of yet!

您可以在顶级解析器上使用-combinator,因此当您实际到达EOF时,就会出现错误。应该处理顶级解析器中的Incomplete-results,例如,通过对读取缓冲区进行扩展并重新尝试。

您可以将解析器封装在本地到当前单元的complete()-parser中,并对其进行测试。某物的曲调

代码语言:javascript
复制
#[test]
fn match_positive_integer() {
    let (_, res) = complete(number("0")).unwrap();
    assert_eq!("0", res);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57914504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档