1use nom::{2 bytes::complete::tag,3 character::complete::{char, one_of},4 combinator::{map_res, recognize},5 error::{FromExternalError, ParseError},6 multi::{many0, many1},7 sequence::delimited,8 IResult,9};1011fn newline(input: &str) -> IResult<&str, char> {12 char('\n')(input)13}14pub fn newline0(input: &str) -> IResult<&str, ()> {15 let (input, _) = many0(newline)(input)?;16 Ok((input, ()))17}18pub fn newline1(input: &str) -> IResult<&str, ()> {19 let (input, _) = many1(newline)(input)?;20 Ok((input, ()))21}2223pub fn bind<'a, F: 'a, T: Copy, O, E: ParseError<&'a str> + FromExternalError<&'a str, ()>>(24 inner: F,25 val: T,26) -> impl FnMut(&'a str) -> IResult<&'a str, T, E>27where28 F: FnMut(&'a str) -> IResult<&'a str, O, E>,29{30 map_res(inner, move |_| -> Result<T, ()> { Ok(val) })31}3233// Parse on of the given strings and return the given value.34pub fn str<'a, T: Copy, E: ParseError<&'a str> + FromExternalError<&'a str, ()> + 'a>(35 name: &'a str,36 val: T,37) -> impl FnMut(&'a str) -> IResult<&'a str, T, E> {38 bind(tag(name), val)39}4041pub fn digits(input: &str) -> IResult<&str, &str> {42 recognize(many1(one_of("0123456789")))(input)43}4445pub fn parse_i64(input: &str) -> IResult<&str, i64> {46 map_res(digits, |input: &str| i64::from_str_radix(input, 10))(input)47}4849// TODO: Use generics to refactor parse_u64 and parse_i6450pub fn parse_u64(input: &str) -> IResult<&str, u64> {51 map_res(digits, |input: &str| u64::from_str_radix(input, 10))(input)52}5354pub fn ws<'a, F: 'a, O, E: ParseError<&'a str>>(55 inner: F,56) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>57where58 F: Fn(&'a str) -> IResult<&'a str, O, E>,59{60 // See https://c9x.me/compile/doc/il-v1.1.html#Spacing61 delimited(many0(one_of(" \t")), inner, many0(one_of(" \t")))62}