From 3eb3db5bda48fa975e5651f3fd7122b86886783b Mon Sep 17 00:00:00 2001 From: John Turner Date: Thu, 30 Oct 2025 14:00:10 +0000 Subject: change sexpr function to return a closure, and give it a comment --- tests/sexpr.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/sexpr.rs b/tests/sexpr.rs index 328d868..e5024ef 100644 --- a/tests/sexpr.rs +++ b/tests/sexpr.rs @@ -30,15 +30,19 @@ fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> { numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap())) } -fn sexpr<'a>(it: InputIter<&'a str>) -> ParserResult<&'a str, Sexpr> { - sexpr - .separated_list(whitespace(), 0..) - .delimited_by(tag("("), tag(")")) - .map(|output| Sexpr::List(output)) - .or(atom()) - .or(string()) - .or(int()) - .parse(it) +// 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_list(whitespace(), 0..) + .delimited_by(tag("("), tag(")")) + .map(|output| Sexpr::List(output)) + .or(atom()) + .or(string()) + .or(int()) + .parse(it) + } } #[test] @@ -62,5 +66,5 @@ fn test_sexpr() { let input = r#"(let ((a "hello") (b 2)))"#; let it = InputIter::new(input); - dbg!(sexpr(it).unwrap()); + dbg!(sexpr().parse_finished(it).unwrap()); } -- cgit v1.2.3