And the following is a reimplementation of the example in Nom's module documentation, with added support for negative integers:
// https://github.com/utkarshkukreti/munch.rs/blob/62907a57d0d598bd5570c4726bbd0251bd66152f/examples/arithmetic.rs
pub fn expr(str: &str, from: usize) -> munch::Result<i64, munch::str::Error<'static>> {
use munch::str::*;
let ws = P(TakeWhile(char::is_whitespace));
let integer = P(Capture((Optional('-'), TakeWhile1(|ch| ch.is_digit(10))))
.map(|str| str.parse().unwrap()));
let factor = (P('(') >> ws >> expr << ws << ')' | integer) << ws;
let term = factor.repeat(1..)
.join('*'.or('/') << ws)
.fold(|| 0, |_, x| x, |acc, op, x| match op {
'*' => acc * x,
'/' => acc / x,
_ => unreachable!(),
});
term.repeat(1..)
.join('+'.or('-') << ws)
.fold(|| 0, |_, x| x, |acc, op, x| match op {
'+' => acc + x,
'-' => acc - x,
_ => unreachable!(),
})
.parse(str, from)
}
pub fn parse(str: &str) -> Result<i64, (usize, munch::str::Error<'static>)> {
use munch::str::*;
let ws = P(TakeWhile(char::is_whitespace));
(ws >> expr << ws << End).parse(str, 0).map(|(_, output)| output)
}
(Yes, it's cheating a bit since Nom doesn't have a built-in combinator for join + fold yet so their example is more verbose than it would have been otherwise.)