使用nom和nom_locate生成短错误消息



根据本教程,我正在尝试使用nom和nom_locate进行解析。我只想输出格式:

Error: line 5, column 1

但目前我得到:

Error: Parsing Failure: ParseError { span: LocatedSpan { offset: 37, line: 5, fragment: "{{G]nK(1)key [J]n", extra: () }, message: "Error: line 5, column 1" }

相关代码:


pub type Span<'a> = LocatedSpan<&'a str>;
pub type IResult<'a, O> = nom::IResult<Span<'a>, O, ParseError<'a>>;

#[derive(Debug, PartialEq)]
pub struct ParseError<'a> {
span: Span<'a>,
message: String,
}
impl<'a> ParseError<'a> {
pub fn new(message: String, span: Span<'a>) -> Self {
Self {
span,
message,
}
}
}
impl<'a> nom::error::ParseError<Span<'a>> for ParseError<'a> {
fn from_error_kind(input: Span<'a>, _: nom::error::ErrorKind) -> Self {
Self::new(format!("Error: line {}, column {}", input.location_line(), input.location_line()), input)
}
fn append(input: Span<'a>, _: nom::error::ErrorKind, _: Self) -> Self {
Self::new(format!("Error: line {}, column {}", input.location_line(), input.location_line()), input)
}
fn from_char(input: Span<'a>, _: char) -> Self {
Self::new(format!("Error: line {}, column {}", input.location_line(), input.location_line()), input)
}
}
pub fn job(s: Span) -> IResult<Vec<entities::Step>> {
let (s, steps) = many1(job_lines)(s)?;
Ok((s, steps))
}
fn job_lines(s: Span) -> IResult<entities::Step> {
let (s, name) = match step_name(s) {
Ok((s, name)) => (s, name),
Err(nom::Err::Error(_)) => {
let line = s.location_line();
let column = s.get_column();
return Err(nom::Err::Failure(ParseError::new(
format!("Error: line {}, column {}", line, column),
s,
)));
},
Err(e) => return Err(e),
};
Ok((s, name))
}

主要相关错误代码:

let steps = match input::parsers::job(input::parsers::Span::new(&input)) {
Ok((_, steps)) => steps,
Err(error) => {
eprintln!("{}", error);
std::process::exit(1)
}
};

我需要做些什么才能得到短错误消息而不是长错误消息?

编辑:我从自定义ParseError中删除了span属性,然后Error输出变为:

Parsing Failure: ParseError { message: "Error: line 5, column 1" }

好多了,但问题仍然存在:除了信息本身,我能得到所有东西吗?

正如您所推测的,errornom::Err::Err,也就是enum,因此您需要在这一点上进行匹配以获得内部错误:

let steps = match input::parsers::job(input::parsers::Span::new(&input)) {
Ok((_, steps)) => steps,
Err(nom::Err::Failure (error)) => {
eprintln!("{}", error.message);
std::process::exit(1)
},
Err(error) => {
eprintln!("Unknown error: {}", error);
std::process::exit(1)
},
};

相关内容

  • 没有找到相关文章

最新更新