@@ -38,30 +38,37 @@ impl CharacterClass {
38
38
}
39
39
}
40
40
41
- struct State {
41
+ struct State < T > {
42
42
index : uint ,
43
43
chars : CharacterClass ,
44
44
next_states : ~[ uint ] ,
45
- acceptance : bool
45
+ acceptance : bool ,
46
+ metadata : Option < T >
46
47
}
47
48
48
- impl State {
49
- pub fn new ( index : uint , chars : CharacterClass ) -> State {
50
- State { index : index , chars : chars , next_states : ~ [ ] , acceptance : false }
49
+ impl < T > Eq for State < T > {
50
+ fn eq ( & self , other : & State < T > ) -> bool {
51
+ self . index == other . index
51
52
}
52
53
}
53
54
54
- pub struct NFA {
55
- states : ~[ State ]
55
+ impl < T > State < T > {
56
+ pub fn new ( index : uint , chars : CharacterClass ) -> State < T > {
57
+ State { index : index, chars : chars, next_states : ~[ ] , acceptance : false , metadata : None }
58
+ }
59
+ }
60
+
61
+ pub struct NFA < T > {
62
+ states : ~[ State < T > ]
56
63
}
57
64
58
- impl NFA {
59
- pub fn new ( ) -> NFA {
65
+ impl < T > NFA < T > {
66
+ pub fn new ( ) -> NFA < T > {
60
67
let root = State :: new ( 0 , CharacterClass :: valid ( "" ) ) ;
61
68
NFA { states : ~[ root] }
62
69
}
63
70
64
- pub fn process < ' a > ( & ' a self , string : & str ) -> Result < ~[ uint ] , ~str > {
71
+ pub fn process < ' a > ( & ' a self , string : & str ) -> Result < ~[ & ' a State < T > ] , ~str > {
65
72
let mut current = ~[ self . get ( 0 ) ] ;
66
73
67
74
for char in string. chars ( ) {
@@ -75,7 +82,7 @@ impl NFA {
75
82
}
76
83
77
84
let returned = current. iter ( ) . filter_map ( |& state| {
78
- if state. acceptance { Some ( state. index ) } else { None }
85
+ if state. acceptance { Some ( state) } else { None }
79
86
} ) . to_owned_vec ( ) ;
80
87
81
88
if returned. is_empty ( ) {
@@ -85,7 +92,7 @@ impl NFA {
85
92
}
86
93
}
87
94
88
- fn process_char < ' a > ( & ' a self , states : ~[ & State ] , char : & char ) -> ~[ & ' a State ] {
95
+ fn process_char < ' a > ( & ' a self , states : ~[ & State < T > ] , char : & char ) -> ~[ & ' a State < T > ] {
89
96
let mut returned = ~[ ] ;
90
97
91
98
for state in states. iter ( ) {
@@ -101,11 +108,11 @@ impl NFA {
101
108
returned
102
109
}
103
110
104
- pub fn get < ' a > ( & ' a self , state : uint ) -> & ' a State {
111
+ pub fn get < ' a > ( & ' a self , state : uint ) -> & ' a State < T > {
105
112
& self . states [ state]
106
113
}
107
114
108
- pub fn get_mut < ' a > ( & ' a mut self , state : uint ) -> & ' a mut State {
115
+ pub fn get_mut < ' a > ( & ' a mut self , state : uint ) -> & ' a mut State < T > {
109
116
& mut self . states [ state]
110
117
}
111
118
@@ -134,6 +141,10 @@ impl NFA {
134
141
self . get_mut ( index) . acceptance = true ;
135
142
}
136
143
144
+ pub fn metadata ( & mut self , index : uint , metadata : T ) {
145
+ self . get_mut ( index) . metadata = Some ( metadata) ;
146
+ }
147
+
137
148
fn new_state ( & mut self , chars : CharacterClass ) -> uint {
138
149
let index = self . states . len ( ) ;
139
150
let state = State :: new ( index, chars) ;
@@ -144,7 +155,7 @@ impl NFA {
144
155
145
156
#[ test]
146
157
fn basic_test ( ) {
147
- let mut nfa = NFA :: new ( ) ;
158
+ let mut nfa = NFA :: < ( ) > :: new ( ) ;
148
159
let a = nfa. put ( 0 , CharacterClass :: valid ( "h" ) ) ;
149
160
let b = nfa. put ( a, CharacterClass :: valid ( "e" ) ) ;
150
161
let c = nfa. put ( b, CharacterClass :: valid ( "l" ) ) ;
@@ -154,12 +165,12 @@ fn basic_test() {
154
165
155
166
let states = nfa. process ( "hello" ) ;
156
167
157
- assert ! ( states. unwrap( ) == ~[ e ] , "You didn't get the right final state" ) ;
168
+ assert ! ( states. unwrap( ) == ~[ nfa . get ( e ) ] , "You didn't get the right final state" ) ;
158
169
}
159
170
160
171
#[ test]
161
172
fn multiple_solutions ( ) {
162
- let mut nfa = NFA :: new ( ) ;
173
+ let mut nfa = NFA :: < ( ) > :: new ( ) ;
163
174
let a1 = nfa. put ( 0 , CharacterClass :: valid ( "n" ) ) ;
164
175
let b1 = nfa. put ( a1, CharacterClass :: valid ( "e" ) ) ;
165
176
let c1 = nfa. put ( b1, CharacterClass :: valid ( "w" ) ) ;
@@ -172,12 +183,12 @@ fn multiple_solutions() {
172
183
173
184
let states = nfa. process ( "new" ) ;
174
185
175
- assert ! ( states. unwrap( ) == ~[ c1 , c2 ] , "The two states were not found" ) ;
186
+ assert ! ( states. unwrap( ) == ~[ nfa . get ( c1 ) , nfa . get ( c2 ) ] , "The two states were not found" ) ;
176
187
}
177
188
178
189
#[ test]
179
190
fn multiple_paths ( ) {
180
- let mut nfa = NFA :: new ( ) ;
191
+ let mut nfa = NFA :: < ( ) > :: new ( ) ;
181
192
let a = nfa. put ( 0 , CharacterClass :: valid ( "t" ) ) ; // t
182
193
let b1 = nfa. put ( a, CharacterClass :: valid ( "h" ) ) ; // th
183
194
let c1 = nfa. put ( b1, CharacterClass :: valid ( "o" ) ) ; // tho
@@ -196,15 +207,15 @@ fn multiple_paths() {
196
207
let thom = nfa. process ( "thom" ) ;
197
208
let nope = nfa. process ( "nope" ) ;
198
209
199
- assert ! ( thomas. unwrap( ) == ~[ f1 ] , "thomas was parsed correctly" ) ;
200
- assert ! ( tom. unwrap( ) == ~[ c2 ] , "tom was parsed correctly" ) ;
210
+ assert ! ( thomas. unwrap( ) == ~[ nfa . get ( f1 ) ] , "thomas was parsed correctly" ) ;
211
+ assert ! ( tom. unwrap( ) == ~[ nfa . get ( c2 ) ] , "tom was parsed correctly" ) ;
201
212
assert ! ( thom. is_err( ) , "thom didn't reach an acceptance state" ) ;
202
213
assert ! ( nope. is_err( ) , "nope wasn't parsed" ) ;
203
214
}
204
215
205
216
#[ test]
206
217
fn repetitions ( ) {
207
- let mut nfa = NFA :: new ( ) ;
218
+ let mut nfa = NFA :: < ( ) > :: new ( ) ;
208
219
let a = nfa. put ( 0 , CharacterClass :: valid ( "p" ) ) ; // p
209
220
let b = nfa. put ( a, CharacterClass :: valid ( "o" ) ) ; // po
210
221
let c = nfa. put ( b, CharacterClass :: valid ( "s" ) ) ; // pos
@@ -220,14 +231,14 @@ fn repetitions() {
220
231
let new_post = nfa. process ( "posts/new" ) ;
221
232
let invalid = nfa. process ( "posts/" ) ;
222
233
223
- assert ! ( post. unwrap( ) == ~[ g ] , "posts/1 was parsed" ) ;
224
- assert ! ( new_post. unwrap( ) == ~[ g ] , "posts/new was parsed" ) ;
234
+ assert ! ( post. unwrap( ) == ~[ nfa . get ( g ) ] , "posts/1 was parsed" ) ;
235
+ assert ! ( new_post. unwrap( ) == ~[ nfa . get ( g ) ] , "posts/new was parsed" ) ;
225
236
assert ! ( invalid. is_err( ) , "posts/ was invalid" ) ;
226
237
}
227
238
228
239
#[ test]
229
240
fn repetitions_with_ambiguous ( ) {
230
- let mut nfa = NFA :: new ( ) ;
241
+ let mut nfa = NFA :: < ( ) > :: new ( ) ;
231
242
let a = nfa. put ( 0 , CharacterClass :: valid ( "p" ) ) ; // p
232
243
let b = nfa. put ( a, CharacterClass :: valid ( "o" ) ) ; // po
233
244
let c = nfa. put ( b, CharacterClass :: valid ( "s" ) ) ; // pos
@@ -248,7 +259,7 @@ fn repetitions_with_ambiguous() {
248
259
let ambiguous = nfa. process ( "posts/new" ) ;
249
260
let invalid = nfa. process ( "posts/" ) ;
250
261
251
- assert ! ( post. unwrap( ) == ~[ g1 ] , "posts/1 was parsed" ) ;
252
- assert ! ( ambiguous. unwrap( ) == ~[ g1 , i2 ] , "posts/new was ambiguous" ) ;
262
+ assert ! ( post. unwrap( ) == ~[ nfa . get ( g1 ) ] , "posts/1 was parsed" ) ;
263
+ assert ! ( ambiguous. unwrap( ) == ~[ nfa . get ( g1 ) , nfa . get ( i2 ) ] , "posts/new was ambiguous" ) ;
253
264
assert ! ( invalid. is_err( ) , "posts/ was invalid" ) ;
254
265
}
0 commit comments