diff --git a/src/regexp/token.rs b/src/regexp/token.rs --- a/src/regexp/token.rs +++ b/src/regexp/token.rs @@ -27,30 +27,30 @@ impl fmt::Display for ParsingError { } } -pub trait Token { - fn is_skippable(&self) -> bool {false} - fn list_first(&self) -> Vec; - fn list_last(&self) -> Vec; - fn list_neighbours(&self) -> Vec<(usize, usize)>; -} - pub struct Symbol { position: usize } pub struct Asterisk { - content: Box + content: Box } pub struct Plus { - content: Box + content: Box } pub struct Chain { - content: Vec> + content: Vec> } -impl Token for Symbol { +pub enum Token { + Symbol(Symbol), + Asterisk(Asterisk), + Plus(Plus), + Chain(Chain) +} + +impl Symbol { fn list_first(&self) -> Vec { return vec![self.position]; } @@ -64,9 +64,7 @@ impl Token for Symbol { } } -impl Token for Asterisk { - fn is_skippable(&self) -> bool {true} - +impl Asterisk { fn list_first(&self) -> Vec { return self.content.list_first(); } @@ -88,7 +86,7 @@ impl Token for Asterisk { } } -impl Token for Plus { +impl Plus { fn list_first(&self) -> Vec { return self.content.list_first(); } @@ -110,7 +108,7 @@ impl Token for Plus { } } -impl Token for Chain { +impl Chain { fn is_skippable(&self) -> bool { return self.content.iter().all(|x| x.is_skippable()); } @@ -137,7 +135,7 @@ impl Token for Chain { fn list_neighbours(&self) -> Vec<(usize, usize)> { let mut res = Vec::new(); - let mut previous: Vec<&Box> = Vec::new(); + let mut previous: Vec<&Box> = Vec::new(); for token in self.content.iter() { for t in previous.iter() { for x in t.list_last() { @@ -159,6 +157,44 @@ impl Token for Chain { } } +impl Token { + pub fn is_skippable(&self) -> bool { + match self { + Token::Symbol(_) => false, + Token::Asterisk(_) => true, + Token::Plus(_) => false, + Token::Chain(t) => t.is_skippable() + } + } + + pub fn list_first(&self) -> Vec { + match self { + Token::Symbol(t) => t.list_first(), + Token::Asterisk(t) => t.list_first(), + Token::Plus(t) => t.list_first(), + Token::Chain(t) => t.list_first() + } + } + + pub fn list_last(&self) -> Vec { + match self { + Token::Symbol(t) => t.list_last(), + Token::Asterisk(t) => t.list_last(), + Token::Plus(t) => t.list_last(), + Token::Chain(t) => t.list_last() + } + } + + pub fn list_neighbours(&self) -> Vec<(usize, usize)> { + match self { + Token::Symbol(t) => t.list_neighbours(), + Token::Asterisk(t) => t.list_neighbours(), + Token::Plus(t) => t.list_neighbours(), + Token::Chain(t) => t.list_neighbours() + } + } +} + fn find_closing_parenthesis(s: &String) -> Option { let chars: Vec = s.chars().collect(); let mut counter = 0; @@ -172,9 +208,9 @@ fn find_closing_parenthesis(s: &String) return None; } -pub fn parse(pattern: &String, offset: usize) -> Result { +pub fn parse(pattern: &String, offset: usize) -> Result { let chars: Vec = pattern.chars().collect(); - let mut res: Vec> = Vec::new(); + let mut res: Vec> = Vec::new(); let mut i = 0; while i < pattern.len() { let c = chars[i]; @@ -187,25 +223,25 @@ pub fn parse(pattern: &String, offset: u } '*' => { let token = res.pop().ok_or(ParsingError::Asterisk{s: pattern.clone(), pos: i})?; - res.push(Box::new(Asterisk{content: token})); + res.push(Box::new(Token::Asterisk(Asterisk{content: token}))); i += 1; } '+' => { let token = res.pop().ok_or(ParsingError::Plus{s: pattern.clone(), pos: i})?; - res.push(Box::new(Plus{content: token})); + res.push(Box::new(Token::Plus(Plus{content: token}))); i += 1; } ')' => { return Err(ParsingError::OpeningParenthesis {s: pattern.clone(), pos: i}); } - c => { - res.push(Box::new(Symbol{position: i+offset})); + _c => { + res.push(Box::new(Token::Symbol(Symbol{position: i+offset}))); i += 1; } } } - return Ok(Chain{content: res}); + return Ok(Token::Chain(Chain{content: res})); } mod test {