pub type ParseResult<'a,I,O> = std::result::Result<(&'a [I],O),&'a [I]>;
pub trait Parser<'a,I,O>: {
fn parse(&self, input:&'a [I]) -> ParseResult<'a,I,O>;
fn option(self) -> impl Parser<'a,I,Option<O>> + Clone;
fn more(self,no_zero:bool) -> impl Parser<'a,I,Vec<O>> + Clone;
}
impl<'a,I:'a,F,O> Parser<'a,I,O> for F
where
F: Fn(&'a[I]) -> ParseResult<'a,I,O> + Clone,
{
fn parse(&self, input:&'a [I]) -> ParseResult<'a,I,O> { self(input) }
fn option(self) -> impl Parser<'a,I,Option<O>>+Clone { option(self) }
fn more(self,no_zero:bool) -> impl Parser<'a,I,Vec<O>>+Clone { more(self,no_zero) }
}
pub fn take<'a,T,P>(predicat: P) -> impl Parser<'a,T,&'a[T]>+Clone
where
T: 'a,
P: Fn(&'a[T]) -> usize + Clone,
{
move |input: &'a[T]| {
let i = predicat(input);
if i>0 { return Ok(split_at_revers(input, i)); }
Err(input)
}
}
pub fn any<'a,T:'a+Eq+Clone>(pattern: &'a[T]) -> impl Fn(&'a[T]) -> usize+'a+Clone {
|input| { if input.len()>0 && pattern.contains(&input[0]) { 1 } else { 0 } }
}
pub fn starts_with<'a,T:'a+Eq+Clone>(pattern: &'a[T]) -> impl Fn(&'a[T]) -> usize+'a+Clone {
|input| { if input.starts_with(pattern) { pattern.len() } else { 0 } }
}
pub fn starts_with_any<'a,T:'a+Eq+Clone>(pattern: &'a[&'a[T]]) -> impl Fn(&'a[T]) -> usize+'a+Clone {
move |input| {
for i in pattern { if input.starts_with(i) { return pattern.len() }; };
0
}
}
#[derive(Clone)]
pub enum SeqCount {
Max(usize),
Exact(usize),
Range((usize,usize)),
None,
}
pub fn seq<'a,P,T:'a+Eq+Clone>(p: P, count:SeqCount) -> impl Fn(&'a[T]) -> usize+'a+Clone
where
P: Fn(& T) -> bool+Clone+'a,
{ move |input| {
let mut c:usize = 0;
match count {
SeqCount::None => for i in input { if p(i) {c+=1;} else {break;} },
SeqCount::Max(x) => for i in input { if c<x&&p(i) {c+=1;} else {break;} },
SeqCount::Exact(x) => { for i in input { if c<x&&p(i) {c+=1;} else {break;} } if c!=x {c=0;}; },
SeqCount::Range((x,y))=> { for i in input { if c<y&&p(i) {c+=1;} else {break;} } if c<x {c=0;}; },
}
c
}}
pub fn map<'a,T:'a,F,P,R1,R2>(parser: P, map_fn: F) -> impl Parser<'a,T,R2>+Clone
where
P: Parser<'a,T,R1>+Clone,
F: Fn(R1) -> R2+Clone,
{
move |input| {
parser
.parse(input)
.map(|(next_input, result)| (next_input, map_fn(result)))
}
}
pub fn option<'a,T:'a,P,R>(parser: P) -> impl Parser<'a,T,Option<R>>+Clone
where
P: Parser<'a,T,R>+Clone,
{
move |input| {
match parser.parse(input) {
Ok((input,r)) => Ok((input,Some(r))),
_ => Ok((input,None))
}}
}
pub fn pair<'a,T:'a,P1,P2,R1,R2>(p1:P1,p2:P2) -> impl Parser<'a,T,(R1,R2)>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
move |input| {
p1.parse(input).and_then(|(next_input,r1)| {
p2.parse(next_input).map(|(next_input,r2)| (next_input,(r1,r2))) })
}
}
pub fn left<'a,T:'a,P1,P2,R1,R2>(p1:P1,p2:P2) -> impl Parser<'a,T,R1>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
map(pair(p1,p2),|(l,_)|l)
}
pub fn right<'a,T:'a,P1,P2,R1,R2>(p1:P1,p2:P2) -> impl Parser<'a,T,R2>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
map(pair(p1,p2),|(_,r)|r)
}
pub fn right_opt<'a,T:'a,P1,P2,R1,R2>(p1:P1,p2:P2) -> impl Parser<'a,T,R2>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
move |input| {
if let Ok((input,_)) = p1.parse(input) { p2.parse(input) }
else { p2.parse(input) }
}
}
pub fn left_opt<'a,T:'a,P1,P2,R1,R2>(p1:P1,p2:P2) -> impl Parser<'a,T,R1>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
move |input| {
p1.parse(input).map(|(next_input, r1)| {
match p2.parse(next_input) {
Ok((next_input,_)) => (next_input,r1),
_ => (next_input,r1),
}
})
}
}
pub fn find<'a,T:'a,P1,P2,R1,R2>(step:P1,p:P2) -> impl Parser<'a,T,R2>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
{
move |input: &'a[T]| {
let mut next_input1 = input;
while let Ok((next_input2,_)) = step.parse(next_input1) {
let r = p.parse(next_input1);
if r.is_ok() { return r; }
next_input1 = next_input2;
}
Err(input)
}
}
pub const NO_ZERO:bool = true;
pub const ZERO:bool = false;
pub fn more<'a,T:'a,P,R>(p:P,no_zero:bool) -> impl Parser<'a,T,Vec<R>>+Clone
where
P: Parser<'a,T,R>+Clone,
{
move |mut input: &'a[T]| {
let mut result = Vec::new();
while let Ok((next_input,item)) = p.parse(input) {
input = next_input;
result.push(item);
}
if no_zero && result.is_empty() { Err(input) }
else { Ok((input,result)) }
}
}
pub fn alt<'a,T:'a,P,R>(p:&'a[P]) -> impl Parser<'a,T,R>+Clone
where
P: Parser<'a,T,R>+Clone,
{
move |input: &'a[T]| {
for x in p {
let result = x.parse(input);
match result {
Ok(_) => { return result; },
_ => { continue; },
}
}
Err(input)
}
}
pub fn sep_pair<'a,T:'a,P1,P_,P2,R1,R2,R_>(p1:P1,sep:P_,p2:P2) -> impl Parser<'a,T,(R1,R2)>+Clone
where
P1: Parser<'a,T,R1>+Clone,
P2: Parser<'a,T,R2>+Clone,
P_: Parser<'a,T,R_>+Clone,
{
pair(left(p1,sep),p2)
}
#[inline]
pub fn split_at_revers<'a, T>(input: &'a [T], count: usize) -> (&'a [T], &'a [T]) {
(&input[count..], &input[..count])
}
fn drop<I>(_: I) -> () {
()
}