如何从许多0中传播Nom fail上下文?



我有一个Nom解析器,解析字符串,但失败的关键字。

当给定关键字时,下面的解析器正确地失败。

但是由于遇到关键字而失败的错误消息没有传播。

问题是,当label失败时,many0(label)成功了,少了一个结果。随后,eof失败了,因为并非所有内容都被解析了。这正确地失败了,但是错误消息丢失了。

如何传播本地错误消息?

(参见下面操场上的代码)

use nom::bytes::complete::{take_while, take_while1};
use nom::error::{VerboseError};
use nom::multi::{many0};
use nom::{IResult};
use nom::error::{context};
use nom::combinator::{eof, fail};
type ParseResult<'input, Out> = IResult<&'input str, Out, VerboseError<&'input str>>;
fn label(s1: &str) -> ParseResult<&str> {
let (s2, a) = take_while1(|c: char| c.is_alphabetic())(s1)?;
let (s3, _) = take_while(|c: char| c.is_whitespace())(s2)?;
if a == "derp" {
return context("this message is lost", fail)(s1);
}
Ok((s3, a))
}
fn parse(s: &str) -> ParseResult<Vec<&str>> {
let (s, labels) = many0(label)(s)?;
let (s, _) = eof(s)?;
Ok((s, labels))
}
fn main() {
println!("{:?}", parse("foo bar herp flerp"));
// Ok(("", ["foo", "bar", "herp", "flerp"]))
// This fails with Nom(Eof), both Nom(Fail) and context is lost
println!("{:?}", parse("foo bar herp derp"));
// Err(Error(VerboseError { errors: [("derp", Nom(Eof))] }))
}

您可以使用cut来阻止many0在失败情况下探索替代方案(消耗更少):

use nom::combinator::cut;
return cut(context("this message is lost", fail))(s1);

游乐场

相关内容

  • 没有找到相关文章

最新更新