Just use repeated combinator

This commit is contained in:
Greg Shuflin 2022-10-19 22:06:10 -07:00
parent 567ea60642
commit 0d4ea42678
3 changed files with 9 additions and 43 deletions

View File

@ -95,40 +95,6 @@ where
}
}
pub fn zero_or_more<P, I, O>(parser: P) -> impl Parser<I, Vec<O>, I>
where
P: Parser<I, O, I>,
I: Copy,
{
move |mut input| {
let mut results = Vec::new();
while let Ok((item, rest)) = parser.parse(input) {
results.push(item);
input = rest;
}
Ok((results, input))
}
}
pub fn one_or_more<P, I, O>(parser: P) -> impl Parser<I, Vec<O>, I>
where
P: Parser<I, O, I> + 'static,
I: Copy + 'static,
O: 'static,
{
let parser = std::rc::Rc::new(parser);
parser
.clone()
.then(zero_or_more(parser))
.map(|(first, rest)| {
let mut output = vec![first];
output.extend(rest.into_iter());
output
})
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -12,7 +12,7 @@ pub use parser::{ParseResult, Parser};
mod tests {
use super::*;
use crate::choice::choice;
use crate::combinators::{one_or_more, zero_or_more};
use crate::combinators::repeated;
use crate::primitives::{any_char, literal, literal_char, one_of, pred};
use crate::sequence::seq;
use std::collections::HashMap;
@ -54,8 +54,8 @@ mod tests {
let json_number_inner = choice((
seq((
one_or_more(digit()),
literal(".").then(zero_or_more(digit())).optional(),
repeated(digit()).at_least(1),
literal(".").then(repeated(digit())).optional(),
))
.map(|(mut digits, maybe_more)| {
if let Some((point, more)) = maybe_more {
@ -64,7 +64,7 @@ mod tests {
}
digits.into_iter().collect::<String>()
}),
seq((literal("."), one_or_more(digit()))).map(|(_point, digits)| {
seq((literal("."), repeated(digit()).at_least(1))).map(|(_point, digits)| {
let mut d = vec!["."];
d.extend(digits.into_iter());
d.into_iter().collect::<String>()

View File

@ -110,7 +110,7 @@ where
#[cfg(test)]
mod test {
use super::*;
use crate::combinators::zero_or_more;
use crate::combinators::repeated;
use crate::primitives::{identifier, literal};
#[test]
@ -128,16 +128,16 @@ mod test {
fn test_seq() {
let p = seq((
literal("bong").to(10),
zero_or_more(literal(" ")).to(()),
repeated(literal(" ")).to(()),
literal("hits").to(20),
));
assert_eq!(p.parse("bong hits").unwrap(), ((10, (), 20), ""));
let p = seq((
literal("alpha").to(10),
zero_or_more(literal(" ")).to(()),
zero_or_more(literal("-")).to(()),
zero_or_more(literal(" ")),
repeated(literal(" ")).to(()),
repeated(literal("-")).to(()),
repeated(literal(" ")),
literal("beta"),
));
assert_eq!(