use nom::{
branch::alt,
bytes::complete::tag,
character::complete::char,
character::complete::{digit1 as digit, space0 as space},
combinator::map_res,
multi::fold_many0,
sequence::{delimited, pair},
IResult,
};
// Parser definition
use std::str::FromStr;
// We parse any expr surrounded by parens, ignoring all whitespaces around those fn parens(i: &str) -> IResult<&str, i64> {
delimited(space, delimited(tag("("), expr, tag(")")), space)(i)
}
// We transform an integer string into a i64, ignoring surrounding whitespaces // We look for a digit suite, and try to convert it. // If either str::from_utf8 or FromStr::from_str fail, // we fallback to the parens parser defined above fn factor(i: &str) -> IResult<&str, i64> {
alt((
map_res(delimited(space, digit, space), FromStr::from_str),
parens,
))(i)
}
// We read an initial factor and for each time we find // a * or / operator followed by another factor, we do // the math by folding everything fn term(i: &str) -> IResult<&str, i64> { let (i, init) = factor(i)?;
fold_many0(
pair(alt((char('*'), char('/'))), factor), move || init,
|acc, (op, val): (char, i64)| { if op == '*' {
acc * val
} else {
acc / val
}
},
)(i)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.