首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nom解析器借用检查器问题

nom解析器借用检查器问题
EN

Stack Overflow用户
提问于 2019-03-15 14:30:07
回答 2查看 548关注 0票数 4

我有这个锈蚀程序使用nom 4.2.2。(我冒昧地扩展了nom解析器函数。)

代码语言:javascript
复制
extern crate failure;
extern crate nom;

use failure::Error;
use std::fs::File;
use std::io::Read;

fn nom_parser(i: &[u8]) -> ::nom::IResult<&[u8], String, u32> {
    { ::nom::lib::std::result::Result::Ok((i, ("foo".to_owned()))) }
}

fn my_parser(buf: &[u8]) -> Result<(&[u8], String), Error> {
  Ok((buf, "foo".to_owned()))
}

fn main() -> Result<(), Error> {
  let handler = |mut entries: String| { entries.clear() };
  loop {
    let mut buf = Vec::new();
    File::open("/etc/hosts")?.read_to_end(&mut buf)?;
    let res = nom_parser(&buf)?.1;
    // let res = my_parser(&buf)?.1;
    handler(res);
  }
}

使用rustc 1.33.0 (2aa4c46cf 2019-02-28)编译此程序将产生以下问题:

代码语言:javascript
复制
error[E0597]: `buf` does not live long enough
  --> nom-parsing/src/main.rs:21:26
   |
21 |     let res = nom_parser(&buf)?.1;
   |               -----------^^^^-
   |               |          |
   |               |          borrowed value does not live long enough
   |               argument requires that `buf` is borrowed for `'static`
...
24 |   }
   |   - `buf` dropped here while still borrowed

切换到解析器的注释掉版本,编译就可以了。my_parsernom_parser有什么不同?谁在借buf?我应该如何更改程序以安抚借阅检查程序?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-15 15:00:39

代码语言:javascript
复制
let res = nom_parser(&buf)?.1;
                          ^ here

您正在使用?运算符将错误从main中传播出去。IResult<&[u8], String, u32> = Result<(&[u8], String), nom::Err<&[u8], u32>>.因此,如果出现错误,&buf将作为其一部分返回,因此即使在main函数退出之后,它也必须保持活动状态,但它不会,因为bufmain中的局部变量。

在您的示例中,nom_parser从不返回错误,但是验证只关心类型和函数签名。

要修复它,您应该在传播错误之前以某种方式处理它。例如:

代码语言:javascript
复制
let res = nom_parser(&buf).map_err(|_| failure::format_err!("Parsing failed!"))?.1;

注意,Err中的IResult并不总是硬错误。它可能是nom::Err::Incomplete,意味着如果提供了更多数据,解析可能会成功,或者nom::Err::Error意味着解析器没有匹配输入(因此,alt!中的另一个解析器可能会成功),或者nom::Err::Failure,意味着在解析过程中发生了一些真正的错误。根据具体情况,您可能会认为它们都是失败的,或者以不同的方式处理它们。

票数 8
EN

Stack Overflow用户

发布于 2019-03-15 15:14:51

这个问题似乎是在IResult<I, O, E = u32>中出现的,它将花费在Result<(I, O), Err<I, E>>

如您所见,当您使用?时,您可能返回的Err仍然可以包含对I类型的引用,这是您的&[u8],并从您的函数返回。

函数返回此引用的唯一方法是,该引用的生存期不以函数'static结束

对于您的问题,一个简单的解决方案是将&[u8]更改为Vec<u8>,即使我不知道您要用它做什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55184864

复制
相关文章

相似问题

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