196 lines
5.7 KiB
Rust
196 lines
5.7 KiB
Rust
use crate::parser::{ParseResult, Parser, ParserInput, Representation};
|
|
|
|
pub fn tuple2<P1, P2, I, O1, O2, E>(parser1: P1, parser2: P2) -> impl Parser<I, (O1, O2), E>
|
|
where
|
|
I: ParserInput,
|
|
P1: Parser<I, O1, E>,
|
|
P2: Parser<I, O2, E>,
|
|
{
|
|
seq((parser1, parser2))
|
|
}
|
|
|
|
pub fn seq<T, I, O, E>(sequence: T) -> impl Parser<I, O, E>
|
|
where
|
|
I: ParserInput,
|
|
T: Sequence<I, O, E>,
|
|
{
|
|
let rep = sequence.representation();
|
|
let p = move |input| sequence.parse(input);
|
|
(p, rep)
|
|
}
|
|
|
|
/* TODO - eventually rewrite this parser combinator in Schala. Seeing what this
|
|
* code that makes heavy use of type variables and abstraction over types looks like
|
|
* in Schala's type system should be educational
|
|
*/
|
|
|
|
pub trait Sequence<I, O, E> {
|
|
fn parse(&self, input: I) -> ParseResult<I, O, E>;
|
|
fn representation(&self) -> Representation;
|
|
}
|
|
|
|
impl<I, O1, O2, E, P1, P2> Sequence<I, (O1, O2), E> for (P1, P2)
|
|
where
|
|
I: ParserInput,
|
|
P1: Parser<I, O1, E>,
|
|
P2: Parser<I, O2, E>,
|
|
{
|
|
fn parse(&self, input: I) -> ParseResult<I, (O1, O2), E> {
|
|
let parser1 = &self.0;
|
|
let parser2 = &self.1;
|
|
parser1.parse(input).and_then(|(result1, rest1)| {
|
|
parser2
|
|
.parse(rest1)
|
|
.map(|(result2, rest2)| ((result1, result2), rest2))
|
|
})
|
|
}
|
|
|
|
fn representation(&self) -> Representation {
|
|
let mut iter = [self.0.representation(), self.1.representation()].into_iter();
|
|
Representation::from_sequence(&mut iter)
|
|
}
|
|
}
|
|
|
|
impl<I, O1, O2, O3, E, P1, P2, P3> Sequence<I, (O1, O2, O3), E> for (P1, P2, P3)
|
|
where
|
|
I: ParserInput,
|
|
P1: Parser<I, O1, E>,
|
|
P2: Parser<I, O2, E>,
|
|
P3: Parser<I, O3, E>,
|
|
{
|
|
fn parse(&self, input: I) -> ParseResult<I, (O1, O2, O3), E> {
|
|
let parser1 = &self.0;
|
|
let parser2 = &self.1;
|
|
let parser3 = &self.2;
|
|
|
|
let (result1, rest1) = parser1.parse(input)?;
|
|
let (result2, rest2) = parser2.parse(rest1)?;
|
|
let (result3, rest3) = parser3.parse(rest2)?;
|
|
|
|
Ok(((result1, result2, result3), rest3))
|
|
}
|
|
|
|
fn representation(&self) -> Representation {
|
|
let mut iter = [
|
|
self.0.representation(),
|
|
self.1.representation(),
|
|
self.2.representation(),
|
|
]
|
|
.into_iter();
|
|
Representation::from_sequence(&mut iter)
|
|
}
|
|
}
|
|
|
|
impl<I, O1, O2, O3, O4, E, P1, P2, P3, P4> Sequence<I, (O1, O2, O3, O4), E> for (P1, P2, P3, P4)
|
|
where
|
|
I: ParserInput,
|
|
P1: Parser<I, O1, E>,
|
|
P2: Parser<I, O2, E>,
|
|
P3: Parser<I, O3, E>,
|
|
P4: Parser<I, O4, E>,
|
|
{
|
|
fn parse(&self, input: I) -> ParseResult<I, (O1, O2, O3, O4), E> {
|
|
let parser1 = &self.0;
|
|
let parser2 = &self.1;
|
|
let parser3 = &self.2;
|
|
let parser4 = &self.3;
|
|
|
|
let (result1, rest1) = parser1.parse(input)?;
|
|
let (result2, rest2) = parser2.parse(rest1)?;
|
|
let (result3, rest3) = parser3.parse(rest2)?;
|
|
let (result4, rest4) = parser4.parse(rest3)?;
|
|
|
|
Ok(((result1, result2, result3, result4), rest4))
|
|
}
|
|
|
|
fn representation(&self) -> Representation {
|
|
let mut iter = [
|
|
self.0.representation(),
|
|
self.1.representation(),
|
|
self.2.representation(),
|
|
self.3.representation(),
|
|
]
|
|
.into_iter();
|
|
Representation::from_sequence(&mut iter)
|
|
}
|
|
}
|
|
|
|
impl<I, O1, O2, O3, O4, O5, E, P1, P2, P3, P4, P5> Sequence<I, (O1, O2, O3, O4, O5), E>
|
|
for (P1, P2, P3, P4, P5)
|
|
where
|
|
I: ParserInput,
|
|
P1: Parser<I, O1, E>,
|
|
P2: Parser<I, O2, E>,
|
|
P3: Parser<I, O3, E>,
|
|
P4: Parser<I, O4, E>,
|
|
P5: Parser<I, O5, E>,
|
|
{
|
|
fn parse(&self, input: I) -> ParseResult<I, (O1, O2, O3, O4, O5), E> {
|
|
let parser1 = &self.0;
|
|
let parser2 = &self.1;
|
|
let parser3 = &self.2;
|
|
let parser4 = &self.3;
|
|
let parser5 = &self.4;
|
|
|
|
let (result1, rest1) = parser1.parse(input)?;
|
|
let (result2, rest2) = parser2.parse(rest1)?;
|
|
let (result3, rest3) = parser3.parse(rest2)?;
|
|
let (result4, rest4) = parser4.parse(rest3)?;
|
|
let (result5, rest5) = parser5.parse(rest4)?;
|
|
|
|
Ok(((result1, result2, result3, result4, result5), rest5))
|
|
}
|
|
|
|
fn representation(&self) -> Representation {
|
|
let mut iter = [
|
|
self.0.representation(),
|
|
self.1.representation(),
|
|
self.2.representation(),
|
|
self.3.representation(),
|
|
self.4.representation(),
|
|
]
|
|
.into_iter();
|
|
Representation::from_sequence(&mut iter)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use crate::combinators::repeated;
|
|
use crate::primitives::{identifier, literal};
|
|
|
|
#[test]
|
|
fn test_tuple2() {
|
|
let p = tuple2(identifier, tuple2(literal(" "), literal("ruts")));
|
|
let (output, _rest) = p.parse("fort1 ruts").unwrap();
|
|
assert_eq!(output, ("fort1".into(), (" ", "ruts")));
|
|
|
|
let p = identifier.then(literal(" ")).then(literal("ruts"));
|
|
let (output, _rest) = p.parse("fort1 ruts").unwrap();
|
|
assert_eq!(output, (("fort1".into(), " "), "ruts"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_seq() {
|
|
let p = seq((
|
|
literal("bong").to(10),
|
|
repeated(literal(" ")).to(()),
|
|
literal("hits").to(20),
|
|
));
|
|
assert_eq!(p.parse("bong hits").unwrap(), ((10, (), 20), ""));
|
|
|
|
let p = seq((
|
|
literal("alpha").to(10),
|
|
repeated(literal(" ")).to(()),
|
|
repeated(literal("-")).to(()),
|
|
repeated(literal(" ")),
|
|
literal("beta"),
|
|
));
|
|
assert_eq!(
|
|
p.parse("alpha ------ beta gamma").unwrap(),
|
|
((10, (), (), vec![" ", " ", " "], "beta"), " gamma")
|
|
);
|
|
}
|
|
}
|