Skip to content

Commit

Permalink
feat: traversal test
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVikasRushi committed Jun 1, 2024
1 parent 9de8f0f commit 2329b99
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 15 deletions.
125 changes: 125 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@ name = "regExp-Engine"
version = "0.1.0"
edition = "2021"

[dependencies]
[dependencies.uuid]
version = "1.8.0"
features = [
"v4", # Lets you generate random UUIDs
"fast-rng", # Use a faster (but still sufficiently random) RNG
"macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
]
17 changes: 6 additions & 11 deletions src/nfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ impl NFA {
nfa
}

pub fn test(&self, _string: &str) -> bool {
self.in_state.borrow().test(_string)
}

pub fn concat_pair(first: &mut NFA, second: &mut NFA) -> NFA {
first.out_state.borrow_mut().accepting = false;
second.out_state.borrow_mut().accepting = true;
Expand Down Expand Up @@ -113,7 +117,6 @@ mod test {
use std::cell::RefCell;
use std::rc::Rc;


#[test]
fn test_concat_pair() {
let mut first = NFA::char("a");
Expand Down Expand Up @@ -197,7 +200,6 @@ mod test {
assert_eq!(final_nfa.in_state.borrow().accepting, false);
assert_eq!(final_nfa.out_state.borrow().accepting, true);


let epsilon_transit = final_nfa
.in_state
.borrow()
Expand All @@ -206,20 +208,13 @@ mod test {
assert!(Rc::ptr_eq(&epsilon_transit[0], &first.in_state));
assert!(Rc::ptr_eq(&epsilon_transit[1], &second.in_state));

let first_out_transit = first
.out_state
.borrow()
.get_transition_for_symbol(EPSILON);
let first_out_transit = first.out_state.borrow().get_transition_for_symbol(EPSILON);
assert_eq!(first_out_transit.len(), 1);
assert!(Rc::ptr_eq(&first_out_transit[0], &final_nfa.out_state));

let second_out_transit = second
.out_state
.borrow()
.get_transition_for_symbol(EPSILON);
let second_out_transit = second.out_state.borrow().get_transition_for_symbol(EPSILON);
assert_eq!(second_out_transit.len(), 1);
assert!(Rc::ptr_eq(&second_out_transit[0], &final_nfa.out_state));

}

#[test]
Expand Down
81 changes: 78 additions & 3 deletions src/state.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc};

use uuid::Uuid;

pub const EPSILON: &str = "ε";

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct State {
pub accepting: bool,
pub transition_map: HashMap<String, Vec<Rc<RefCell<State>>>>,
pub label: Uuid,
}

impl State {
pub fn new(is_accepting: bool) -> State {
State {
accepting: is_accepting,
transition_map: HashMap::new(),
label: Uuid::new_v4(),
}
}

Expand All @@ -29,14 +33,73 @@ impl State {
None => Vec::new(),
}
}

pub fn test(&self, _string: &str) -> bool {
return self.test_helper(_string, HashMap::new());
}

pub fn test_helper(&self, _string: &str, mut is_visited: HashMap<Uuid, bool>) -> bool {
let label = self.label.borrow();

if *is_visited.get(label).unwrap() {
return false;
}

is_visited.insert(*label, true);

if _string.is_empty() {
if *self.accepting.borrow() {
return true;
}

let epsilon_transitions = self.get_transition_for_symbol(EPSILON);

for next_state in epsilon_transitions.iter() {
if next_state.borrow_mut().test_helper("", is_visited.clone()) {
return true;
}
}
return false;
}
let first_char = &_string[0..1];
let rest_of_string = &_string[1..];

let symbol_transitions = self.get_transition_for_symbol(first_char);

for next_state in symbol_transitions.iter() {
if next_state
.borrow_mut()
.test_helper(rest_of_string, is_visited.clone())
{
return true;
}
}

let eplision_transition_for_next_state = self.get_transition_for_symbol(EPSILON);

for next_state in eplision_transition_for_next_state.iter() {
if next_state
.borrow_mut()
.test_helper(_string, is_visited.clone())
{
return true;
}
}
return false;
}
}

#[cfg(test)]
mod test {

use super::*;
use crate::nfa::NFA;

use crate::state::State;
use std::cell::RefCell;
use std::rc::Rc;

use super::EPSILON;

#[test]
fn test_add_and_get_transition() {
let s1 = Rc::new(RefCell::new(State::new(false)));
Expand Down Expand Up @@ -96,4 +159,16 @@ mod test {
}
}
}

#[test]
fn test_helper() {
let first_nfa = NFA::new();

first_nfa
.in_state
.borrow_mut()
.add_transition_for_symbol(EPSILON, first_nfa.out_state.clone());

let result = first_nfa.test(EPSILON);
}
}

0 comments on commit 2329b99

Please sign in to comment.