#![deny(unused_imports)] use core::{ clone::Clone, cmp::PartialEq, fmt, iter::{IntoIterator, Iterator}, marker::Sized, ops::Range, }; use crate::{ input::{Character, Input, InputIter}, mode::{Check, Emit, Mode}, }; pub mod input; pub mod mode; pub type Span = Range; pub type ParserOk = (InputIter, O); pub type ParserResult = Result::Output>, ::Output>>; pub trait Trace { fn trace(parser: &str, input: InputIter); } pub struct DebugTracer; impl Trace for DebugTracer where I: Input + fmt::Debug, { fn trace(parser: &str, input: InputIter) { eprintln!("{}:{:?}", parser, input) } } impl Trace for () where I: Input, { fn trace(_: &str, _: InputIter) {} } #[derive(Debug)] pub enum ParserFinishedError { Err(InputIter), Unfinished(InputIter), } pub trait Parser: Sized { type Output; fn run>( &self, it: InputIter, ) -> ParserResult; fn parse(&self, it: InputIter) -> ParserResult { self.run::(it) } fn check(&self, it: InputIter) -> ParserResult { self.run::(it) } fn trace>(&self, it: InputIter) -> ParserResult { self.run::(it) } fn parse_finished(&self, it: InputIter) -> Result> { match self.parse(it) { Ok((rest, output)) if rest.is_finished() => Ok(output), Ok((rest, _)) => Err(ParserFinishedError::Unfinished(rest)), Err(rest) => Err(ParserFinishedError::Err(rest)), } } fn check_finished(&self, it: InputIter) -> Result<(), ParserFinishedError> { match self.parse(it) { Ok((rest, _)) if rest.is_finished() => Ok(()), Ok((rest, _)) => Err(ParserFinishedError::Unfinished(rest)), Err(rest) => Err(ParserFinishedError::Err(rest)), } } fn map(self, f: F) -> impl Parser where F: Fn(Self::Output) -> O, { Map { parser: self, f } } fn and

(self, right: P) -> impl Parser where P: Parser, { And { left: self, right } } fn or(self, right: P) -> impl Parser where Self: Parser, P: Parser, { Or { left: self, right } } fn and_not

(self, not: P) -> impl Parser where P: Parser, { AndNot { parser: self, not } } fn preceded_by

(self, preceded: P) -> impl Parser where P: Parser, { PrecededBy { parser: self, preceded, } } fn followed_by

(self, followed: P) -> impl Parser where P: Parser, { FollowedBy { parser: self, followed, } } fn delimited_by(self, left: P1, right: P2) -> impl Parser where P1: Parser, P2: Parser, { DelimitedBy { parser: self, left, right, } } fn recognize(self) -> impl Parser { Recognize { parser: self } } fn verify_input(self, checker: C) -> impl Parser where C: Parser, { VerifyInput { parser: self, checker, } } fn verify_output(self, checker: F) -> impl Parser where F: Fn(&Self::Output) -> bool, { VerifyOutput { parser: self, checker, } } fn ignore(self) -> impl Parser { Ignore { parser: self } } fn opt(self) -> impl Parser> { Opt { parser: self } } fn not(self) -> impl Parser { Not { parser: self } } fn repeated(self) -> impl ParserIter { Repeated { parser: self } } fn separated_by

(self, delimiter: P) -> impl ParserIter where P: Parser, { SeparatedBy { parser: self, delimiter, } } fn find(self) -> impl ParserIter { Find { parser: self } } } pub trait ParserIter { type Item; fn next( &self, it: InputIter, ) -> Option>; fn many(self) -> impl Parser> where Self: Sized, { Many { parser: self } } fn at_least(self, count: usize) -> impl Parser> where Self: Sized, { AtLeast { parser: self, count, } } fn at_most(self, count: usize) -> impl Parser> where Self: Sized, { AtMost { parser: self, count, } } } struct Repeated

{ parser: P, } impl ParserIter for Repeated

where I: Input, P: Parser, { type Item = P::Output; fn next( &self, it: InputIter, ) -> Option> { if it.is_finished() { None } else { match self.parser.run::(it) { Ok((rest, output)) => Some(Ok((rest, output))), Err(rest) => Some(Err(rest)), } } } } struct SeparatedBy { parser: P1, delimiter: P2, } impl ParserIter for SeparatedBy where I: Input, P1: Parser, P2: Parser, { type Item = P1::Output; fn next( &self, it: InputIter, ) -> Option> { if it.is_finished() { None } else { let (rest, output) = match self.parser.run::(it) { Ok((rest, output)) => (rest, output), Err(rest) => return Some(Err(rest)), }; let rest = match self.delimiter.check(rest.clone()) { Ok((rest, _)) => rest, _ => rest, }; Some(Ok((rest, output))) } } } struct AtLeast

{ parser: P, count: usize, } impl Parser for AtLeast

where I: Input, P: ParserIter, { type Output = Vec; fn run>( &self, mut it: InputIter, ) -> ParserResult { let mut outputs = OM::bind(|| Vec::new()); let mut i = 0; while !it.is_finished() { it = match self.parser.next::(it.clone()) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); acc }); rest } Some(Err(_)) if i >= self.count => break, Some(Err(rest)) => return Err(rest), None if i >= self.count => break, None => return Err(EM::bind(|| it)), }; i += 1; } if i >= self.count { Ok((it, outputs)) } else { Err(EM::bind(|| it)) } } } struct AtMost

{ parser: P, count: usize, } impl Parser for AtMost

where I: Input, P: ParserIter, { type Output = Vec; fn run>( &self, mut it: InputIter, ) -> ParserResult { let mut outputs = OM::bind(|| Vec::new()); for _ in 0..self.count { it = match self.parser.next::(it.clone()) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); acc }); rest } _ => break, } } Ok((it, outputs)) } } struct Many

{ parser: P, } impl Parser for Many

where I: Input, P: ParserIter, { type Output = Vec; fn run>( &self, mut it: InputIter, ) -> ParserResult { let mut outputs = OM::bind(|| Vec::new()); while !it.is_finished() { it = match self.parser.next::(it.clone()) { Some(Ok((rest, output))) => { outputs = OM::combine(outputs, output, |mut acc, e| { acc.push(e); acc }); rest } _ => break, }; } Ok((it, outputs)) } } impl Parser for F where I: Input, F: Fn(InputIter) -> Result, InputIter>, { type Output = O; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("fn", it.clone()); match self(it) { Ok((rest, output)) => Ok((rest, OM::bind(|| output))), Err(rest) => Err(EM::bind(|| rest)), } } } struct Map { parser: P, f: F, } impl Parser for Map where I: Input, P: Parser, F: Fn(P::Output) -> O, { type Output = O; fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.run::(it) { Ok((rest, output)) => Ok((rest, OM::map(output, |o| (self.f)(o)))), Err(rest) => Err(rest), } } } struct And { left: P1, right: P2, } impl Parser for And where I: Input, P1: Parser, P2: Parser, { type Output = (P1::Output, P2::Output); fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("and", it.clone()); let (rest, o1) = match self.left.run::(it) { Ok((rest, output)) => (rest, output), Err(rest) => return Err(rest), }; let (rest, o2) = match self.right.run::(rest) { Ok((rest, output)) => (rest, output), Err(rest) => return Err(rest), }; Ok((rest, OM::combine(o1, o2, |o1, o2| (o1, o2)))) } } struct AndNot { parser: P1, not: P2, } impl Parser for AndNot where I: Input, P1: Parser, P2: Parser, { type Output = P1::Output; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("andnot", it.clone()); match self.not.run::(it.clone()) { Ok(_) => return Err(EM::bind(|| it.clone())), _ => (), }; self.parser.run::(it) } } struct Or { left: P1, right: P2, } impl Parser for Or where I: Input, P1: Parser, P2: Parser, { type Output = O; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("or", it.clone()); if let Ok((rest, output)) = self.left.run::(it.clone()) { return Ok((rest, output)); }; if let Ok((rest, output)) = self.right.run::(it.clone()) { return Ok((rest, output)); }; Err(EM::bind(|| it)) } } pub struct Take { amt: usize, } impl Parser for Take where I: Input, { type Output = I; fn run>( &self, mut it: InputIter, ) -> ParserResult { Tracer::trace("take", it.clone()); let start = it.clone(); for _ in 0..self.amt { match it.next() { Some(_) => continue, None => return Err(EM::bind(|| it)), } } Ok(( it.clone(), OM::bind(|| it.input.slice(start.position()..it.position())), )) } } pub fn take(amt: usize) -> impl Parser where I: Input, { Take { amt } } pub struct OneOf { it: It, } impl Parser for OneOf where I: Input, I::Item: PartialEq, It: IntoIterator + Clone, { type Output = I::Item; fn run>( &self, mut it: InputIter, ) -> ParserResult { Tracer::trace("oneof", it.clone()); let start = it.clone(); match it.next() { Some((_, item)) if self.it.clone().into_iter().any(|i| item == i) => { Ok((it, OM::bind(|| item))) } _ => Err(EM::bind(|| start)), } } } pub fn one_of(it: It) -> impl Parser where I: Input, I::Item: PartialEq, It: IntoIterator + Clone, { OneOf { it } } pub struct If { f: F, } impl Parser for If where I: Input, F: Fn(&I::Item) -> bool, { type Output = I::Item; fn run>( &self, mut it: InputIter, ) -> ParserResult { Tracer::trace("if", it.clone()); match it.next() { Some((_, output)) if (self.f)(&output) => Ok((it, OM::bind(|| output))), _ => Err(EM::bind(|| it)), } } } pub fn r#if(f: F) -> impl Parser where I: Input, F: Fn(&I::Item) -> bool, { If { f } } struct PrecededBy { parser: P1, preceded: P2, } impl Parser for PrecededBy where I: Input, P1: Parser, P2: Parser, { type Output = P1::Output; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("preceded by", it.clone()); let rest = match self.preceded.check(it.clone()) { Ok((rest, _)) => rest, Err(_) => return Err(EM::bind(|| it)), }; self.parser.run::(rest) } } pub struct FollowedBy { parser: P1, followed: P2, } impl Parser for FollowedBy where I: Input, P1: Parser, P2: Parser, { type Output = P1::Output; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("followed by", it.clone()); let (rest, output) = match self.parser.run::(it) { Ok((rest, output)) => (rest, output), Err(rest) => return Err(rest), }; let Ok((rest, _)) = self.followed.check(rest.clone()) else { return Err(EM::bind(|| rest.clone())); }; Ok((rest, output)) } } struct DelimitedBy { parser: P1, left: P2, right: P3, } impl Parser for DelimitedBy where I: Input, P1: Parser, P2: Parser, P3: Parser, { type Output = P1::Output; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("delimited by", it.clone()); let rest = match self.left.check(it.clone()) { Ok((rest, _)) => rest, Err(_) => return Err(EM::bind(|| it)), }; let (rest, output) = match self.parser.run::(rest.clone()) { Ok((rest, output)) => (rest, output), Err(rest) => return Err(rest), }; let Ok((rest, _)) = self.right.check(rest.clone()) else { return Err(EM::bind(|| rest)); }; Ok((rest, output)) } } struct Recognize

{ parser: P, } impl Parser for Recognize

where I: Input, P: Parser, { type Output = I; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("recognize", it.clone()); let start = it.clone(); let rest = match self.parser.check(it.clone()) { Ok((rest, _)) => rest, Err(_) => return Err(EM::bind(|| it)), }; Ok(( rest.clone(), OM::bind(|| it.input.slice(start.position()..rest.position())), )) } } struct Tag(T); impl Parser for Tag where I: Input + PartialEq, T: Input, { type Output = I; fn run>( &self, it: InputIter, ) -> ParserResult { Tracer::trace("tag", it.clone()); match take(self.0.len()).parse(it.clone()) { Ok((rest, output)) if output == self.0 => Ok((rest, OM::bind(|| output))), Ok(_) => return Err(EM::bind(|| it)), Err(rest) => return Err(EM::bind(|| rest)), } } } pub fn tag(tag: T) -> impl Parser where I: Input + PartialEq, T: Input, { Tag(tag) } struct Not

{ parser: P, } impl Parser for Not

where I: Input, P: Parser, { type Output = (); fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.check(it.clone()) { Ok(_) => Err(EM::bind(|| it)), Err(_) => Ok((it, OM::bind(|| ()))), } } } struct Opt

{ parser: P, } impl Parser for Opt

where I: Input, P: Parser, { type Output = Option; fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.run::(it.clone()) { Ok((rest, output)) => Ok((rest, OM::map(output, |o| Some(o)))), Err(_) => Ok((it, OM::bind(|| None))), } } } struct VerifyInput { parser: P, checker: C, } impl Parser for VerifyInput where I: Input, P: Parser, C: Parser, { type Output = P::Output; fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.run::(it.clone()) { Ok((rest, output)) if self.checker.check(it.clone()).is_ok() => { Ok((rest, OM::bind(|| output))) } Err(rest) => Err(EM::bind(|| rest)), _ => Err(EM::bind(|| it)), } } } struct VerifyOutput { parser: P, checker: F, } impl Parser for VerifyOutput where I: Input, P: Parser, F: Fn(&P::Output) -> bool, { type Output = P::Output; fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.parse(it.clone()) { Ok((rest, output)) if (self.checker)(&output) => Ok((rest, OM::bind(|| output))), Ok(_) => Err(EM::bind(|| it)), Err(rest) => Err(EM::bind(|| rest)), } } } struct Ignore

{ parser: P, } impl Parser for Ignore

where I: Input, P: Parser, { type Output = (); fn run>( &self, it: InputIter, ) -> ParserResult { match self.parser.check(it) { Ok((rest, _)) => Ok((rest, OM::bind(|| ()))), Err(rest) => Err(EM::bind(|| rest)), } } } struct Eof; impl Parser for Eof where I: Input, { type Output = (); fn run>( &self, it: InputIter, ) -> ParserResult { if it.is_finished() { Ok((it, OM::bind(|| ()))) } else { Err(EM::bind(|| it)) } } } struct Find

{ parser: P, } impl ParserIter for Find

where I: Input, P: Parser, { type Item = P::Output; fn next( &self, mut it: InputIter, ) -> Option> { while !it.is_finished() { it = match self.parser.run::(it.clone()) { Ok((rest, output)) => return Some(Ok((rest, output))), Err(_) => match take(1).check(it.clone()) { Ok((rest, _)) => rest, Err(_) => return None, }, }; } None } } pub fn eof() -> impl Parser where I: Input, { Eof } pub fn alpha() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_alphabetic()) } pub fn alpha1() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_alphabetic()) .repeated() .at_least(1) .recognize() } pub fn numeric() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_numeric()) } pub fn numeric1() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_numeric()) .repeated() .at_least(1) .recognize() } pub fn alphanumeric() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_alphanumeric()) } pub fn alphanumeric1() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_alphanumeric()) .repeated() .at_least(1) .recognize() } pub fn whitespace() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_whitespace()) } pub fn whitespace1() -> impl Parser where I: Input, I::Item: Character, { r#if(|c: &I::Item| c.is_whitespace()) .repeated() .at_least(1) .recognize() } pub fn any() -> impl Parser where I: Input, { r#if(|_| true) } #[cfg(feature = "regex")] pub mod str { use super::*; struct Regex<'a>(&'a regex::Regex); impl<'src, 'regex> Parser<&'src str> for Regex<'regex> { type Output = &'src str; fn run>( &self, it: InputIter<&'src str>, ) -> ParserResult<&'src str, Self::Output, OM, EM> { match self.0.find(it.rest()) { Some(m) => { let output = OM::bind(|| it.rest().slice(m.range())); let (rest, _) = take(m.end()).parse(it).unwrap(); Ok((rest, output)) } None => return Err(EM::bind(|| it.clone())), } } } pub fn regex<'a>(regexp: &'a regex::Regex) -> impl Parser<&'a str, Output = &'a str> { Regex(regexp) } } #[cfg(test)] mod test { use super::*; #[test] fn test_separated_list() { let input = "a b c"; let it = InputIter::new(input); alpha() .separated_by(whitespace()) .at_least(1) .check_finished(it) .unwrap(); } #[test] fn test_find() { let input = "hello world"; let it = InputIter::new(input); assert_eq!( alpha1().find().at_least(1).parse_finished(it).unwrap(), vec!["hello", "world"] ); } #[test] #[cfg(feature = "regex")] fn test_regex_parser() { let it = InputIter::new("abc 123"); match crate::str::regex(®ex::Regex::new("[a-z]+").unwrap()).parse(it) { Ok((rest, output)) => { assert_eq!(output, "abc"); assert_eq!(rest.rest(), " 123"); } _ => panic!(), } } }