Skip to content

Commit 4d8011f

Browse files
committed
Support for repeated states
1 parent d949a43 commit 4d8011f

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/nfa.rs

+55
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ impl NFA {
126126
state
127127
}
128128

129+
pub fn put_state(&mut self, index: uint, child: uint) {
130+
self.get_mut(index).next_states.push(child);
131+
}
132+
129133
pub fn acceptance(&mut self, index: uint) {
130134
self.get_mut(index).acceptance = true;
131135
}
@@ -197,3 +201,54 @@ fn multiple_paths() {
197201
assert!(thom.is_err(), "thom didn't reach an acceptance state");
198202
assert!(nope.is_err(), "nope wasn't parsed");
199203
}
204+
205+
#[test]
206+
fn repetitions() {
207+
let mut nfa = NFA::new();
208+
let a = nfa.put(0, CharacterClass::valid("p")); // p
209+
let b = nfa.put(a, CharacterClass::valid("o")); // po
210+
let c = nfa.put(b, CharacterClass::valid("s")); // pos
211+
let d = nfa.put(c, CharacterClass::valid("t")); // post
212+
let e = nfa.put(d, CharacterClass::valid("s")); // posts
213+
let f = nfa.put(e, CharacterClass::valid("/")); // posts/
214+
let g = nfa.put(f, CharacterClass::invalid("/")); // posts/[^/]
215+
nfa.put_state(g, g);
216+
217+
nfa.acceptance(g);
218+
219+
let post = nfa.process("posts/1");
220+
let new_post = nfa.process("posts/new");
221+
let invalid = nfa.process("posts/");
222+
223+
assert!(post.unwrap() == ~[g], "posts/1 was parsed");
224+
assert!(new_post.unwrap() == ~[g], "posts/new was parsed");
225+
assert!(invalid.is_err(), "posts/ was invalid");
226+
}
227+
228+
#[test]
229+
fn repetitions_with_ambiguous() {
230+
let mut nfa = NFA::new();
231+
let a = nfa.put(0, CharacterClass::valid("p")); // p
232+
let b = nfa.put(a, CharacterClass::valid("o")); // po
233+
let c = nfa.put(b, CharacterClass::valid("s")); // pos
234+
let d = nfa.put(c, CharacterClass::valid("t")); // post
235+
let e = nfa.put(d, CharacterClass::valid("s")); // posts
236+
let f = nfa.put(e, CharacterClass::valid("/")); // posts/
237+
let g1 = nfa.put(f, CharacterClass::invalid("/")); // posts/[^/]
238+
let g2 = nfa.put(f, CharacterClass::valid("n")); // posts/n
239+
let h2 = nfa.put(g2, CharacterClass::valid("e")); // posts/ne
240+
let i2 = nfa.put(h2, CharacterClass::valid("w")); // posts/new
241+
242+
nfa.put_state(g1, g1);
243+
244+
nfa.acceptance(g1);
245+
nfa.acceptance(i2);
246+
247+
let post = nfa.process("posts/1");
248+
let ambiguous = nfa.process("posts/new");
249+
let invalid = nfa.process("posts/");
250+
251+
assert!(post.unwrap() == ~[g1], "posts/1 was parsed");
252+
assert!(ambiguous.unwrap() == ~[g1, i2], "posts/new was ambiguous");
253+
assert!(invalid.is_err(), "posts/ was invalid");
254+
}

0 commit comments

Comments
 (0)