···
+
use crate::dna::DnaRef;
+
use crate::parser::Parser;
+
use crate::pattern::Pattern;
+
use crate::pattern::PatternItem;
+
use crate::template::TemplateItem;
+
groups: Vec<(usize, usize)>,
+
fn do_match(dna: &DnaRef, start: usize, pattern: &Pattern) -> Option<MatchResult> {
+
let mut env = Vec::new();
+
let mut opens = Vec::new();
+
for p in pattern.iter() {
+
PatternItem::Base(b) => {
+
if index >= dna.len() || dna[index] != *b {
+
PatternItem::Skip(n) => {
+
PatternItem::Search(s) => {
+
let mut fallback = Vec::new();
+
fallback.reserve(s.len());
+
let mut j = fallback[i - 1];
+
while j > 0 && s[j] != s[i - 1] {
+
} else if index >= dna.len() {
+
} else if dna[index] == s[cur] {
+
PatternItem::Close => {
+
let start = opens.pop()?;
+
env.push((start, index));
+
return Some(MatchResult {
+
pub fn protect(dna: DnaRef, level: usize) -> DnaRef {
+
let mut cur = dna.clone();
+
.flat_map(|b| match b {
+
Base::I => [Base::C].iter(),
+
Base::C => [Base::F].iter(),
+
Base::F => [Base::P].iter(),
+
Base::P => [Base::I, Base::C].iter(),
+
.map(|b| DnaRef::from_base(*b))
+
pub fn asnat(n: usize) -> DnaRef {
+
let mut v = Vec::new();
+
return v.iter().map(|b| DnaRef::from_base(*b)).collect::<DnaRef>();
+
pub fn match_replace(dna: DnaRef, rna: &mut Vec<Rna>) -> Option<DnaRef> {
+
let mut parser = Parser::new(&dna);
+
let pattern = parser.pattern(rna)?;
+
let template = parser.template(rna)?;
+
let index = parser.index();
+
if let Some(matched) = do_match(&dna, index, &pattern) {
+
let mut replace = DnaRef::new();
+
for t in template.into_iter() {
+
TemplateItem::Base(b) => {
+
// TODO: Implement AddAssign
+
replace = replace + DnaRef::from_base(b);
+
TemplateItem::Ref(n, l) => {
+
let (start, end) = matched.groups[n];
+
let (_, rhs) = dna.split(start);
+
let (group, _) = rhs.split(end - start);
+
replace = replace + protect(group, l);
+
TemplateItem::Len(n) => {
+
let (start, end) = matched.groups[n];
+
replace = replace + asnat(end - start);
+
let (_, remainder) = dna.split(matched.end);
+
return Some(replace + remainder);
+
let (_, rhs) = dna.split(index);
+
fn test_match_bases() {
+
let dna = DnaRef::from_string("CFPICIIC CCCIIC ICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "III");
+
// !{10} -> III on ICFPICFPICFP
+
let dna = DnaRef::from_string("IPICICPIIC CCCIIC ICFPICFPICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "IIIFP");
+
fn test_match_search() {
+
// ?{IIIC} -> <empty> on ICIICIIICICFP
+
let dna = DnaRef::from_string("IFFCCCFIIC IIC ICIICIIICICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "ICFP");
+
fn test_match_groups() {
+
// (!{1})(!{1})(!{1})(!{1}) -> {3}{2}{1}{0} on ICFP
+
let dna = DnaRef::from_string(
+
"IIPIPCPIICIIPIPCPIICIIPIPCPIICIIPIPCPIICIIC IPPCCPIPPICPIPPCPIPPPIIC ICFP",
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "PFCI");
+
fn test_match_protect() {
+
// (!{4}) -> {0}{0,1}{0,2}{0,3} on ICFP
+
let dna = DnaRef::from_string("IIPIPIICPIICIIC IPPPIPCPPIPICPPIPCCPPIIC ICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "ICFPCFPICFPICCFPICCFFP");
+
fn test_match_asnat() {
+
// (!{10}) -> |0| on ICFPICFPICFP
+
let dna = DnaRef::from_string("IIPIPICICPIICIIC IIPPIIC ICFPICFPICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "ICICPFP");
+
// RIPIPIPI -> RCFCFCFC on ICFP
+
let dna = DnaRef::from_string("IIIIPIPIPIIIC IIICFCFCFCIIC ICFP");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "ICFP");
+
let dna = DnaRef::from_string("IIPIPICPIICICIIFICCIFPPIICCFPC");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "PICFC");
+
let dna = DnaRef::from_string("IIPIPICPIICICIIFICCIFCCCPPIICCFPC");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "PIICCFCFFPC");
+
let dna = DnaRef::from_string("IIPIPIICPIICIICCIICFCFC");
+
let mut rna = Vec::new();
+
let res = match_replace(dna, &mut rna);
+
assert!(res.is_some());
+
assert_eq!(res.unwrap().to_string(), "I");