diff --git a/regexp.py b/regexp.py --- a/regexp.py +++ b/regexp.py @@ -52,7 +52,9 @@ class Symbol(Token): return self.value -class Plus(Token): +class Asterisk(Token): + is_skippable = True + def __init__(self, content: Token): self.content = content @@ -69,13 +71,6 @@ class Plus(Token): yield (x, y) def __str__(self): - return str(self.content) + "+" - - -class Asterisk(Plus): - is_skippable = True - - def __str__(self): return str(self.content) + "*" @@ -188,16 +183,9 @@ def parse(pattern, offset=0): raise ParsingError(f'The asterisk operator is missing an argument. Pattern: "{pattern}", position {i}') res.append(Asterisk(token)) i += 1 - elif c == "+": - try: - token = res.pop() - except IndexError as e: - raise ParsingError(f'The plus operator is missing an argument. Pattern: "{pattern}", position {i}') - res.append(Plus(token)) - i += 1 elif c == ")": raise ParsingError(f'An opening parenthesis not found. Pattern: "{pattern}", position: {i}') - elif c == "|": + elif c == "|" or c == "+": is_alternative = True res.append(AlternativeSeparator()) i += 1 diff --git a/src/regexp/token.rs b/src/regexp/token.rs --- a/src/regexp/token.rs +++ b/src/regexp/token.rs @@ -3,7 +3,6 @@ use std::{borrow::Borrow, fmt}; #[derive(Debug, Clone)] pub enum ParsingError { Asterisk {s: String, pos: usize}, - Plus {s: String, pos: usize}, OpeningParenthesis {s: String, pos: usize}, ClosingParenthesis {s: String, pos: usize}, EmptyAlternativeVariant @@ -15,9 +14,6 @@ impl fmt::Display for ParsingError { ParsingError::Asterisk {s, pos} => { write!(f, "The asterisk operator is missing an argument. Pattern \"{s}\", position {pos}") }, - ParsingError::Plus {s, pos} => { - write!(f, "The plus operator is missing an argument. Pattern \"{s}\", position {pos}") - }, ParsingError::OpeningParenthesis {s, pos} => { write!(f, "An opening parenthesis not found. Pattern \"{s}\", position {pos}") }, @@ -39,10 +35,6 @@ pub struct Asterisk { content: Box } -pub struct Plus { - content: Box -} - pub struct Alternative { content: Vec> } @@ -55,7 +47,6 @@ pub enum Token { Lambda, Symbol(Symbol), Asterisk(Asterisk), - Plus(Plus), Alternative(Alternative), AlternativeSeparator, Chain(Chain) @@ -97,28 +88,6 @@ impl Asterisk { } } -impl Plus { - fn list_first(&self) -> Vec { - return self.content.list_first(); - } - - fn list_last(&self) -> Vec { - return self.content.list_last(); - } - - fn list_neighbours(&self) -> Vec<(usize, usize)> { - let mut res = self.content.list_neighbours(); - - for x in self.list_last() { - for y in self.list_first() { - res.push((x, y)); - } - } - - return res; - } -} - impl Alternative { fn new(content: Vec>) -> Result { let mut variants: Vec>> = vec![Vec::new()]; @@ -229,7 +198,6 @@ impl Token { Token::Lambda => true, Token::Symbol(_) => false, Token::Asterisk(_) => true, - Token::Plus(_) => false, Token::Alternative(t) => t.is_skippable(), Token::AlternativeSeparator => panic!(), Token::Chain(t) => t.is_skippable() @@ -241,7 +209,6 @@ impl Token { Token::Lambda => vec![], Token::Symbol(t) => t.list_first(), Token::Asterisk(t) => t.list_first(), - Token::Plus(t) => t.list_first(), Token::Alternative(t) => t.list_first(), Token::AlternativeSeparator => panic!(), Token::Chain(t) => t.list_first() @@ -253,7 +220,6 @@ impl Token { Token::Lambda => vec![], Token::Symbol(t) => t.list_last(), Token::Asterisk(t) => t.list_last(), - Token::Plus(t) => t.list_last(), Token::Alternative(t) => t.list_last(), Token::AlternativeSeparator => panic!(), Token::Chain(t) => t.list_last() @@ -265,7 +231,6 @@ impl Token { Token::Lambda => vec![], Token::Symbol(t) => t.list_neighbours(), Token::Asterisk(t) => t.list_neighbours(), - Token::Plus(t) => t.list_neighbours(), Token::Alternative(t) => t.list_neighbours(), Token::AlternativeSeparator => panic!(), Token::Chain(t) => t.list_neighbours() @@ -305,15 +270,10 @@ pub fn parse(pattern: &String, offset: u 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(Token::Plus(Plus{content: token}))); - i += 1; - } ')' => { return Err(ParsingError::OpeningParenthesis {s: pattern.clone(), pos: i}); } - '|' => { + '|' | '+' => { is_alternative = true; res.push(Box::new(Token::AlternativeSeparator)); i += 1; diff --git a/tests/test_regexp.rs b/tests/test_regexp.rs --- a/tests/test_regexp.rs +++ b/tests/test_regexp.rs @@ -51,24 +51,6 @@ fn test_eval_asterisk_dfa() { } #[test] -fn test_eval_plus_nfa() { - let r = Regexp::new(&String::from("(ab)+")).unwrap(); - assert!(!r.eval(String::from("a"))); - assert!(r.eval(String::from("ab"))); - assert!(r.eval(String::from("abab"))); - assert!(!r.eval(String::from("aabb"))); -} - -#[test] -fn test_eval_plus_dfa() { - let r = Regexp::new(&String::from("(ab)+")).unwrap().determinize(); - assert!(!r.eval(String::from("a"))); - assert!(r.eval(String::from("ab"))); - assert!(r.eval(String::from("abab"))); - assert!(!r.eval(String::from("aabb"))); -} - -#[test] fn test_eval_alternative_nfa() { let r = Regexp::new(&String::from("a|b|c")).unwrap(); assert!(r.eval(String::from("a"))); @@ -121,12 +103,6 @@ fn test_invalid_asterisk() { } #[test] -fn test_invalid_plus() { - let x = Regexp::new(&String::from("+")); - assert!(matches!(x, Err(ParsingError::Plus{s: _, pos: 0}))); -} - -#[test] fn test_invalid_closing_parenthesis() { let x = Regexp::new(&String::from("(a")); assert!(matches!(x, Err(ParsingError::ClosingParenthesis{s: _, pos: 0})));