use crate::base::Base; use crate::pattern::Pattern; use crate::pattern::PatternItem; use crate::rna::Rna; use crate::template::Template; use crate::template::TemplateItem; use std::mem; pub struct Parser where I: Iterator, { iter: I, peeked: Vec, index: usize, } impl Parser where I: Iterator, { pub fn new(iter: I) -> Parser { Parser { iter: iter, peeked: Vec::new(), index: 0, } } pub fn index(&self) -> usize { self.index } fn peek_to(&mut self, n: usize) { while self.peeked.len() < n { if let Some(b) = self.iter.next() { self.peeked.push(b); } else { return; } } } pub fn next_is(&mut self, next: &[Base]) -> bool { self.peek_to(next.len()); if self.peeked.len() < next.len() { return false; } return &self.peeked[..next.len()] == next; } pub fn advance(&mut self, n: usize) { self.peek_to(n); self.index += n; self.peeked.drain(..n); } pub fn nat(&mut self) -> Option { let mut ret = 0; let mut bit = 1; loop { if self.next_is(&[Base::P]) { self.advance(1); return Some(ret); } else if self.next_is(&[Base::I]) || self.next_is(&[Base::F]) { self.advance(1); } else if self.next_is(&[Base::C]) { ret += bit; self.advance(1); } else { return None; } bit *= 2; } } pub fn consts(&mut self) -> Vec { let mut ret = Vec::new(); loop { if self.next_is(&[Base::C]) { self.advance(1); ret.push(Base::I); } else if self.next_is(&[Base::F]) { self.advance(1); ret.push(Base::C); } else if self.next_is(&[Base::P]) { self.advance(1); ret.push(Base::F); } else if self.next_is(&[Base::I, Base::C]) { self.advance(2); ret.push(Base::P); } else { return ret; } } } pub fn pattern(&mut self, rna: &mut Vec) -> Option { let mut ret = Vec::new(); let mut level = 0; loop { if self.next_is(&[Base::C]) { self.advance(1); ret.push(PatternItem::Base(Base::I)); } else if self.next_is(&[Base::F]) { self.advance(1); ret.push(PatternItem::Base(Base::C)); } else if self.next_is(&[Base::P]) { self.advance(1); ret.push(PatternItem::Base(Base::F)); } else if self.next_is(&[Base::I, Base::C]) { self.advance(2); ret.push(PatternItem::Base(Base::P)); } else if self.next_is(&[Base::I, Base::P]) { self.advance(2); let n = self.nat()?; ret.push(PatternItem::Skip(n)); } else if self.next_is(&[Base::I, Base::F]) { self.advance(3); let s = self.consts(); ret.push(PatternItem::Search(s)); } else if self.next_is(&[Base::I, Base::I, Base::P]) { self.advance(3); level += 1; ret.push(PatternItem::Open); } else if self.next_is(&[Base::I, Base::I, Base::C]) || self.next_is(&[Base::I, Base::I, Base::F]) { self.advance(3); if level == 0 { return Some(Pattern::new(ret)); } level -= 1; ret.push(PatternItem::Close); } else if self.next_is(&[Base::I, Base::I, Base::I]) { self.advance(3); self.peek_to(7); let mut r = Vec::new(); mem::swap(&mut r, &mut self.peeked); rna.push(r.try_into().unwrap()); self.index += 7; } else { return None; } } } pub fn template(&mut self, rna: &mut Vec) -> Option