#![allow(dead_code)] use mon::{ Parser, ParserIter, ascii_alpha1, ascii_alphanumeric, ascii_alphanumeric1, ascii_numeric1, ascii_whitespace1, input::InputIter, tag, }; #[derive(Debug)] enum Sexpr { List(Vec), Atom(String), String(String), Int(i64), } fn atom<'a>() -> impl Parser<&'a str, Output = Sexpr> { ascii_alpha1() .and(ascii_alphanumeric().repeated().many()) .recognize() .map(|output: &str| Sexpr::Atom(output.to_string())) } fn string<'a>() -> impl Parser<&'a str, Output = Sexpr> { ascii_alphanumeric1() .delimited_by(tag("\""), tag("\"")) .map(|output: &str| Sexpr::String(output.to_string())) } fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> { ascii_numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap())) } // Recursive parsers must avoid an infinite loop, you can do this // by returning a closure that accepts an InputIter and returns ParserResult. fn sexpr<'a>() -> impl Parser<&'a str, Output = Sexpr> { |it| { sexpr() .separated_by(ascii_whitespace1()) .many() .delimited_by(tag("("), tag(")")) .map(|output| Sexpr::List(output)) .or(atom()) .or(string()) .or(int()) .parse(it) } } #[test] fn test_atom() { let input = "atom"; let it = InputIter::new(input); atom().check_finished(it).unwrap(); } #[test] fn test_string() { let input = r#""string""#; let it = InputIter::new(input); string().check_finished(it).unwrap() } #[test] fn test_sexpr() { let input = r#"(let ((a "hello") (b 2)))"#; let it = InputIter::new(input); dbg!(sexpr().parse_finished(it).unwrap()); }