Move seq into separate module

This commit is contained in:
Greg Shuflin 2022-10-16 17:33:10 -07:00
parent c6b3f51e42
commit c5b351e8ee
2 changed files with 33 additions and 24 deletions

View File

@ -1,6 +1,7 @@
#![feature(assert_matches)] #![feature(assert_matches)]
#![allow(dead_code)] //TODO eventually turn this off #![allow(dead_code)] //TODO eventually turn this off
mod bnf; mod bnf;
mod sequence;
use bnf::Bnf; use bnf::Bnf;
use std::rc::Rc; use std::rc::Rc;
@ -45,7 +46,7 @@ trait Parser<I, O, E> {
E: 'a, E: 'a,
P: Parser<I, O2, E> + 'a, P: Parser<I, O2, E> + 'a,
{ {
BoxedParser::new(seq(self, next_parser)) BoxedParser::new(sequence::seq(self, next_parser))
} }
} }
@ -107,20 +108,6 @@ where
} }
} }
fn seq<P1, P2, I, O1, O2, E>(parser1: P1, parser2: P2) -> impl Parser<I, (O1, O2), E>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
{
move |input| {
parser1.parse(input).and_then(|(result1, rest1)| {
parser2
.parse(rest1)
.map(|(result2, rest2)| ((result1, result2), rest2))
})
}
}
fn pred<P, F, I, O>(parser: P, pred_fn: F) -> impl Parser<I, O, I> fn pred<P, F, I, O>(parser: P, pred_fn: F) -> impl Parser<I, O, I>
where where
P: Parser<I, O, I>, P: Parser<I, O, I>,
@ -237,15 +224,6 @@ mod tests {
assert_matches!(output.unwrap(), (s, " yolo") if s == "A"); 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") );
let p = identifier.then(literal(" ")).then(literal("ruts"));
assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0.0 == "fort1" && r.0.1== " " && r.1 == "ruts");
}
#[test] #[test]
fn test_one_or_more() { fn test_one_or_more() {
let p = one_or_more(literal("bongo ")); let p = one_or_more(literal("bongo "));

31
src/sequence.rs Normal file
View File

@ -0,0 +1,31 @@
use crate::Parser;
pub(crate) fn seq<P1, P2, I, O1, O2, E>(parser1: P1, parser2: P2) -> impl Parser<I, (O1, O2), E>
where
P1: Parser<I, O1, E>,
P2: Parser<I, O2, E>,
{
move |input| {
parser1.parse(input).and_then(|(result1, rest1)| {
parser2
.parse(rest1)
.map(|(result2, rest2)| ((result1, result2), rest2))
})
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::{identifier, literal};
use std::assert_matches::assert_matches;
#[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") );
let p = identifier.then(literal(" ")).then(literal("ruts"));
assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0.0 == "fort1" && r.0.1== " " && r.1 == "ruts");
}
}