ICFP 2007 Contest: https://web.archive.org/web/20090301164728/https://save-endo.cs.uu.nl/

Pattern parsing

Changed files
+78 -7
dna2rna
+1
dna2rna/src/main.rs
···
mod dna;
mod parser;
+
mod pattern;
use crate::dna::*;
+67
dna2rna/src/parser.rs
···
use crate::Base;
use crate::DnaRef;
+
use crate::pattern::Pattern;
+
use crate::pattern::PatternItem;
struct Parser<'a> {
buf: &'a DnaRef,
···
}
}
}
+
+
pub fn pattern(&mut self) -> Option<Pattern> {
+
let mut ret = Vec::new();
+
let mut level = 0;
+
loop {
+
if self.next_is(&[Base::C]) {
+
self.index += 1;
+
ret.push(PatternItem::Base(Base::I));
+
} else if self.next_is(&[Base::F]) {
+
self.index += 1;
+
ret.push(PatternItem::Base(Base::C));
+
} else if self.next_is(&[Base::P]) {
+
self.index += 1;
+
ret.push(PatternItem::Base(Base::F));
+
} else if self.next_is(&[Base::I, Base::C]) {
+
self.index += 2;
+
ret.push(PatternItem::Base(Base::P));
+
} else if self.next_is(&[Base::I, Base::P]) {
+
self.index += 2;
+
let n = self.nat()?;
+
ret.push(PatternItem::Skip(n));
+
} else if self.next_is(&[Base::I, Base::F]) {
+
self.index += 3;
+
let s = self.consts();
+
ret.push(PatternItem::Search(s));
+
} else if self.next_is(&[Base::I, Base::I, Base::P]) {
+
self.index += 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.index += 3;
+
if level == 0 {
+
return Some(ret);
+
}
+
level -= 1;
+
ret.push(PatternItem::Close);
+
} else if self.next_is(&[Base::I, Base::I, Base::I]) {
+
self.index += 10;
+
// TODO: RNA output
+
} else {
+
return None;
+
}
+
}
+
}
}
#[cfg(test)]
···
let mut parser = Parser::new(&dna);
assert_eq!(parser.consts(), &[Base::I, Base::C, Base::F, Base::P]);
assert_eq!(parser.index, 5);
+
}
+
+
#[test]
+
fn test_pattern() {
+
let dna = DnaRef::from_string("CIIC");
+
let mut parser = Parser::new(&dna);
+
assert_eq!(parser.pattern(), Some(vec![PatternItem::Base(Base::I)]));
+
+
let dna = DnaRef::from_string("IIPIPICPIICICIIF");
+
let mut parser = Parser::new(&dna);
+
assert_eq!(
+
parser.pattern(),
+
Some(vec![
+
PatternItem::Open,
+
PatternItem::Skip(2),
+
PatternItem::Close,
+
PatternItem::Base(Base::P)
+
])
+
);
}
}
+10 -7
dna2rna/src/pattern.rs
···
-
use crate::Base;
+
use crate::Base;
+
#[derive(Debug, PartialEq)]
pub enum PatternItem {
-
Base(char),
-
Skip(usize),
-
Search(Vec<Base>),
-
Open,
-
Close
-
}
+
Base(Base),
+
Skip(usize),
+
Search(Vec<Base>),
+
Open,
+
Close,
+
}
+
+
pub type Pattern = Vec<PatternItem>;