diff options
| author | omagdy7 <omar.professional8777@gmail.com> | 2023-11-30 01:32:41 +0200 |
|---|---|---|
| committer | omagdy7 <omar.professional8777@gmail.com> | 2023-11-30 01:32:41 +0200 |
| commit | 1e3ce70c5c0d757cd2abaef809a211a3430cdd26 (patch) | |
| tree | cb4f671c144bb0e12e2d66dc55a397df6ee86ec8 /src/main.rs | |
| parent | 8ef74fd2db43e7f25f65ff2ad8c86e5f5dec3f79 (diff) | |
| download | rex-1e3ce70c5c0d757cd2abaef809a211a3430cdd26.tar.xz rex-1e3ce70c5c0d757cd2abaef809a211a3430cdd26.zip | |
Restructures the project into separate files and added basic NFA functionality
Diffstat (limited to 'src/main.rs')
| -rwxr-xr-x | src/main.rs | 177 |
1 files changed, 15 insertions, 162 deletions
diff --git a/src/main.rs b/src/main.rs index 2d0f9c9..bfe2050 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,166 +1,19 @@ -#![allow(dead_code, unused_variables, unused_mut)] - -macro_rules! Sym { - ($c:expr) => { - RegexToken::Symbol($c) - }; -} - -macro_rules! Star { - ($c:expr) => { - RegexToken::Star(Box::new($c)) - }; -} - -macro_rules! Plus { - ($c:expr) => { - RegexToken::Plus(Box::new($c)) - }; -} - -macro_rules! Concat { - ($a:expr, $b:expr) => { - RegexToken::Concat((Box::new($a), Box::new($b))) - }; -} - -macro_rules! Union { - ($a:expr, $b:expr) => { - RegexToken::Union((Box::new($a), Box::new($b))) - }; -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_concat() { - assert_eq!( - Regex::new(String::from("ab")), - Concat!(Sym!('a'), Sym!('b')) - ) - } - - #[test] - fn test_plus() { - assert_eq!( - Regex::new(String::from("(a|b)+c")), - Concat!(Plus!(Union!(Sym!('a'), Sym!('b'))), Sym!('c')) - ) - } - - #[test] - fn test_union() { - assert_eq!( - Regex::new(String::from("(a|b)")), - Union!(Sym!('a'), Sym!('b')) - ) - } - - #[test] - fn test_none() { - assert_eq!(Regex::new(String::from("")), RegexToken::None) - } - - #[test] - fn test_star() { - assert_eq!( - Regex::new(String::from("a*b")), - Concat!(Star!(Sym!('a')), Sym!('b')) - ) - } -} - -type ReToken = Box<RegexToken>; - -#[derive(Debug, PartialEq, Clone)] -enum RegexToken { - Token(ReToken), - Symbol(char), - Number(usize), - Concat((ReToken, ReToken)), - Union((ReToken, ReToken)), - Plus(ReToken), - Star(ReToken), - Dot, - None, -} - -#[derive(Debug, PartialEq)] -struct Regex {} - -impl Regex { - fn new(input: String) -> RegexToken { - Regex::parse(input) - } - - fn parse(input: String) -> RegexToken { - if input.is_empty() { - return RegexToken::None; - } - - let mut chars = input.chars().peekable(); - let mut parsed_token = Self::parse_token(&mut chars); - - Self::parse_expression(&mut parsed_token, &mut chars) - } - - fn parse_expression( - left: &mut RegexToken, - chars: &mut std::iter::Peekable<std::str::Chars>, - ) -> RegexToken { - while let Some(&next) = chars.peek() { - match next { - '|' => { - chars.next(); // Consume '|' - let right = Self::parse_token(chars); - *left = RegexToken::Union((Box::new(left.clone()), Box::new(right))); - } - '*' => { - chars.next(); // Consume '*' - let right = Self::parse_token(chars); - *left = RegexToken::Concat(( - Box::new(RegexToken::Star(Box::new(left.clone()))), - Box::new(right), - )); - } - '+' => { - chars.next(); // Consume '+' - let right = Self::parse_token(chars); - *left = RegexToken::Concat(( - Box::new(RegexToken::Plus(Box::new(left.clone()))), - Box::new(right), - )); - } - _ => { - let right = Self::parse_token(chars); - if let RegexToken::None = right { - } else { - *left = RegexToken::Concat((Box::new(left.clone()), Box::new(right))); - } - } - } - } - left.clone() - } - - fn parse_token(chars: &mut std::iter::Peekable<std::str::Chars>) -> RegexToken { - match chars.next() { - Some('(') => { - let token = Self::parse(chars.collect()); - chars.next(); // Skip ')' - token - } - Some('.') => RegexToken::Dot, - Some(c) if c.is_ascii_alphanumeric() => Sym!(c), - _ => RegexToken::None, - } - } -} +mod nfa; +mod regex; +use nfa::*; +use regex::*; fn main() { - let input = "((aa)|(bb))"; + let input = "abcdefglmno"; let token = Regex::new(String::from(input)); - println!("{input}\n{:#?}", token) + println!("{input}\n{:#?}", token); + + let mut nfa = NFA::new(); + nfa.regex_to_nfa(token); + nfa.add_state(); + + println!("NFA: {:#?}", nfa); + let inp = "abcdefglmno"; + let output = nfa.simulate(String::from(inp)); + println!("{inp} was = {output}") } |
