aboutsummaryrefslogtreecommitdiff
path: root/src/nfa.rs
diff options
context:
space:
mode:
authoromagdy7 <omar.professional8777@gmail.com>2023-12-04 13:46:37 +0200
committeromagdy7 <omar.professional8777@gmail.com>2023-12-04 13:46:37 +0200
commitfd4049183f9e86e061c8fe440c133451116fc7e2 (patch)
tree1cd0499815f0e12ca87a10ba875e3f1573b437ce /src/nfa.rs
parent253cebb03b9e630189b644bb1023fef2f506f652 (diff)
downloadrex-fd4049183f9e86e061c8fe440c133451116fc7e2.tar.xz
rex-fd4049183f9e86e061c8fe440c133451116fc7e2.zip
Added a From Regex implementation for NFA
Diffstat (limited to 'src/nfa.rs')
-rw-r--r--src/nfa.rs35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/nfa.rs b/src/nfa.rs
index e7b8187..3fc890c 100644
--- a/src/nfa.rs
+++ b/src/nfa.rs
@@ -1,4 +1,4 @@
-use crate::regex::RegexToken;
+use crate::regex::Regex;
use std::{collections::HashMap, str::Chars, usize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@@ -30,6 +30,14 @@ pub struct NFA {
accepting_states: Vec<usize>,
}
+impl From<Regex> for NFA {
+ fn from(regex: Regex) -> Self {
+ let mut nfa = NFA::new();
+ nfa.regex_to_nfa(regex);
+ nfa
+ }
+}
+
impl NFA {
pub fn new() -> Self {
Self {
@@ -47,15 +55,15 @@ impl NFA {
id
}
- pub fn regex_to_nfa_helper(&mut self, input: RegexToken) -> (usize, usize) {
- match input {
- RegexToken::Symbol(ch) => {
+ pub fn regex_to_nfa_helper(&mut self, regex: Regex) -> (usize, usize) {
+ match regex {
+ Regex::Symbol(ch) => {
let first = self.add_state();
let last = self.add_state();
self.add_transition(first, last, Trans::Symbol(ch));
(first, last)
}
- RegexToken::Concat((left, right)) => {
+ Regex::Concat((left, right)) => {
let first = self.add_state();
let (l_first, l_last) = self.regex_to_nfa_helper(*left);
let (r_first, r_last) = self.regex_to_nfa_helper(*right);
@@ -63,7 +71,7 @@ impl NFA {
self.add_transition(l_last, r_first, Trans::Epsilon);
(first, r_last)
}
- RegexToken::Union((left, right)) => {
+ Regex::Union((left, right)) => {
let first = self.add_state();
let (l_first, l_last) = self.regex_to_nfa_helper(*left);
let (r_first, r_last) = self.regex_to_nfa_helper(*right);
@@ -74,8 +82,8 @@ impl NFA {
self.add_transition(r_last, last, Trans::Epsilon);
(first, last)
}
- RegexToken::Plus(_) => todo!(),
- RegexToken::Star(tok) => {
+ Regex::Plus(_) => todo!(),
+ Regex::Star(tok) => {
let first = self.add_state();
let (t_first, t_last) = self.regex_to_nfa_helper(*tok);
self.add_transition(first, t_first, Trans::Epsilon);
@@ -85,18 +93,18 @@ impl NFA {
self.add_transition(t_last, last, Trans::Epsilon);
(first, last)
}
- RegexToken::Dot => {
+ Regex::Dot => {
let first = self.add_state();
(first, first)
}
- RegexToken::None => {
+ Regex::None => {
let state = self.add_state();
(state, state)
}
}
}
- pub fn regex_to_nfa(&mut self, input: RegexToken) {
- let (_, last) = self.regex_to_nfa_helper(input);
+ pub fn regex_to_nfa(&mut self, regex: Regex) {
+ let (_, last) = self.regex_to_nfa_helper(regex);
self.accepting_states.push(last);
}
@@ -145,7 +153,7 @@ impl NFA {
result
}
- pub fn matches(&mut self, input: String) -> bool {
+ pub fn matches(&self, input: String) -> bool {
let chars = input.chars();
self.matches_helper(self.states.get(&self.initial_state).unwrap(), chars)
}
@@ -175,6 +183,7 @@ mod tests {
#[test]
fn test_concat_fail() {
assert!(!test("abc", "abd"));
+ assert!(!test("abc", "abd"));
assert!(!test("abc", "abcc"));
assert!(!test("abc", "notabc"));
assert!(!test("abc", ""));