From 0ee53b8f00786a01cc6bc873f05cf7ba24a7d1ad Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 15 Oct 2022 23:58:05 -0700 Subject: [PATCH] Sequence --- src/lib.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2807dc3..7ac320b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,47 @@ where P: Parser, F: Fn(O1) -> O2, { - move |input| parser.parse(input).map(|(result, rest)| (map_fn(result), rest)) + move |input| { + parser + .parse(input) + .map(|(result, rest)| (map_fn(result), rest)) + } +} + +fn seq(parser1: P1, parser2: P2) -> impl Parser +where + P1: Parser, + P2: Parser, +{ + move |input| { + parser1.parse(input).and_then(|(result1, rest1)| { + parser2 + .parse(rest1) + .map(|(result2, rest2)| ((result1, result2), rest2)) + }) + } +} + +/// Parses a standard identifier in a programming language +fn identifier(input: &str) -> ParseResult<&str, String, &str> { + let mut chars = input.chars(); + let mut buf = String::new(); + + match chars.next() { + Some(ch) if ch.is_alphabetic() => buf.push(ch), + _ => return Err(input), + } + + while let Some(next) = chars.next() { + if next.is_alphanumeric() { + buf.push(next); + } else { + break; + } + } + + let next_index = buf.len(); + Ok((buf, &input[next_index..])) } #[cfg(test)] @@ -42,10 +82,22 @@ mod tests { assert_matches!(output.unwrap(), ("a", " yolo")); } + #[test] + fn test_identifier() { + assert_matches!(identifier("bongo1beans"), Ok((s, "")) if s == "bongo1beans"); + assert_matches!(identifier("2bongo1beans"), Err("2bongo1beans")); + } + #[test] fn test_map() { let lit_a = literal("a"); let output = map(lit_a, |s| s.to_uppercase()).parse("a yolo"); assert_matches!(output.unwrap(), (s, " yolo") if s == "A"); } + + #[test] + fn test_seq() { + let p = seq(identifier, seq(literal(" "), literal("ruts"))); + assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0 == "fort1" && r.1 == (" ", "ruts") ); + } }