From d8a68bcbf3ee34e51461589c5b4116511222237d Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Mon, 29 Jan 2024 04:08:32 -0800 Subject: [PATCH] Sexp parser --- src/combinators.rs | 13 +++++++++++++ src/test/sexp.rs | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/combinators.rs b/src/combinators.rs index f4913f6..5206f0d 100644 --- a/src/combinators.rs +++ b/src/combinators.rs @@ -107,6 +107,19 @@ where allow_trailing: bool, } +impl SeparatedBy +where + D: Parser, + P: Parser, + E: Default, +{ + pub fn allow_trailing(self, allow_trailing: bool) -> Self { + Self { + allow_trailing, + ..self + } + } +} impl Parser, E> for SeparatedBy where D: Parser, diff --git a/src/test/sexp.rs b/src/test/sexp.rs index 0a4d7bd..25552d2 100644 --- a/src/test/sexp.rs +++ b/src/test/sexp.rs @@ -53,7 +53,11 @@ fn parse_expr(input: &str) -> ParseResult<&str, Expr, ()> { fn parse_list(input: &str) -> ParseResult<&str, Expr, ()> { literal_char('(') - .ignore_then(repeated(parse_atom.map(Expr::Atom)).separated_by(whitespace.to(()))) + .ignore_then( + repeated(parse_expr) + .separated_by(repeated(whitespace).at_least(1).to(())) + .allow_trailing(true), + ) .then_ignore(literal_char(')')) .map(Expr::List) .parse(input) @@ -71,4 +75,13 @@ fn test_parse_sexp() { ]) ); assert_eq!(output.1, ""); + + let complex_input = r#" +(add (mul 28 9) + (if (eq a b) (jump #t) (hula 44)) +)"# + .trim(); + + let output = parse_expr(complex_input).unwrap(); + assert_eq!(output.1, ""); }