-
Notifications
You must be signed in to change notification settings - Fork 836
Open
Milestone
Description
First of all, thanks for providing such a great tool for building parsers.
When I built an expression evaluator, I'd like to do certain optimization, for example:
(expr1 or expr2 or expr3) and expr4
if expr1 is true, I'd skip the evaluation of expr2 and expr4, thus the whole sub expr inside brackets would be true.
I'm using fold_many0 for it, but if there's something like fold_many0_while like below, it would be great:
use nom::IResult;
pub enum FoldWhile<T> {
Continue(T),
Done(T),
}
// copied and modified from https://docs.rs/nom/6.1.2/src/nom/multi/mod.rs.html#723-760
pub fn fold_many0_while<I, O, E, F, G, R>(
mut f: F,
init: R,
mut g: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
I: Clone + PartialEq,
F: nom::Parser<I, O, E>,
G: FnMut(R, O) -> FoldWhile<R>,
E: nom::error::ParseError<I>,
R: Clone,
{
use nom::error::ErrorKind;
use nom::Err;
move |i: I| {
let mut res = init.clone();
let mut input = i;
loop {
let i_ = input.clone();
match f.parse(i_) {
Ok((i, o)) => {
// loop trip must always consume (otherwise infinite loops)
if i == input {
return Err(Err::Error(E::from_error_kind(input, ErrorKind::Many0)));
}
res = match g(res, o) {
FoldWhile::Continue(v) => v,
FoldWhile::Done(v) => return Ok((i, v)),
};
input = i;
}
Err(Err::Error(_)) => {
return Ok((input, res));
}
Err(e) => {
return Err(e);
}
}
}
}
}Is there any plan for such features? I'd love to make a PR if this is the direction.
ju1ius
Metadata
Metadata
Assignees
Labels
No labels