fn decimal_number_parser(input: &mut &str) -> PResult<(f64, i32)> {
let sign = || opt(one_of(['-', '+']));
let digits_with_underscores = || {
repeat(1.., alt((digit1.map(Some), '_'.map(|_| None))))
.map(|vd: Vec<Option<&str>>| vd.into_iter().flatten().collect::<Vec<_>>().join(""))
};
let float_digits = || {
(
opt(digits_with_underscores()),
'.',
digits_with_underscores(),
)
.map(|(maybe_predot, _, postdot)| {
maybe_predot
.map(|predot| format!("{predot}.{postdot}"))
.unwrap_or_else(|| format!(".{postdot}"))
})
};
let signed_base = (sign(), alt((float_digits(), digits_with_underscores()))).map(
|(sign, digits): (_, String)| {
if let Some(sign) = sign {
format!("{sign}{digits}")
} else {
digits
}
},
);
let exponent = preceded("e", (sign(), digits_with_underscores()));
(signed_base, opt(exponent))
.try_map(|(base, maybe_exp)| {
let base = base.parse::<f64>()?;
let exponent = if let Some((sign, exponent)) = maybe_exp {
let signed = if let Some(sign) = sign {
format!("{sign}{exponent}")
} else {
exponent
};
signed.parse::<i32>()?
} else {
0
};
Ok::<_, DecimalParseError>((base, exponent))
})
.parse_next(input)
}
fn parse_float(lexer: &mut Lexer<Token>) -> Result<(f64, i32), LexError> {
let target = lexer.slice();
decimal_number_parser.parse(target).map_err(|e| {
// TODO A proper lex error
dbg!(std::any::type_name_of_val(&e));
LexError::Unknown
})
}
#[derive(Debug, Clone, PartialEq, Logos)]