metrale_grammar/fsm/
algorithms.rs1use ahash::AHashSet;
8
9use super::edge::edge_type;
10use super::fsm::Fsm;
11use super::with_start_end::FsmWithStartEnd;
12
13pub const DEFAULT_MAX_STATES: usize = 1_000_000;
15
16impl FsmWithStartEnd {
17 pub fn is_dfa(&mut self) -> bool {
20 if self.is_dfa {
21 return true;
22 }
23 for edges in self.fsm.all_edges() {
24 let mut char_seen = [false; 256];
25 let mut rule_seen: AHashSet<i32> = AHashSet::new();
26 for edge in edges {
27 if edge.is_epsilon() {
28 return false;
29 }
30 if edge.is_char_range() {
31 for c in edge.min..=edge.max {
32 if char_seen[c as usize] {
33 return false;
34 }
35 char_seen[c as usize] = true;
36 }
37 continue;
38 }
39 if edge.is_rule_ref() && !rule_seen.insert(edge.ref_rule_id()) {
40 return false;
41 }
42 }
43 }
44 self.is_dfa = true;
45 true
46 }
47
48 pub fn to_dfa(&self, max_num_states: usize) -> Result<FsmWithStartEnd, String> {
51 if self.num_states() > max_num_states {
52 return Err("The number of states exceeds the limit.".to_string());
53 }
54 let mut dfa = FsmWithStartEnd::new(Fsm::with_states(0), 0, Vec::new(), true);
55 let mut closures: Vec<AHashSet<i32>> = Vec::new();
56
57 let mut closure: AHashSet<i32> = AHashSet::from_iter([self.start as i32]);
58 self.fsm.epsilon_closure(&mut closure);
59 closures.push(closure);
60
61 let mut now_process = 0;
62 while now_process < closures.len() {
63 let mut rules: AHashSet<i32> = AHashSet::new();
64 let mut repeat_aux: AHashSet<i16> = AHashSet::new();
65 let mut interval_ends: std::collections::BTreeSet<i32> =
66 std::collections::BTreeSet::new();
67 let mut allowed = [false; 256];
68 dfa.add_state();
69
70 for &state in &closures[now_process] {
71 if self.is_end_state(state as usize) {
72 dfa.add_end_state(now_process);
73 }
74 for edge in self.fsm.edges(state as usize) {
75 if edge.is_char_range() {
76 interval_ends.insert(edge.min as i32);
77 interval_ends.insert(edge.max as i32 + 1);
78 for c in edge.min..=edge.max {
79 allowed[c as usize] = true;
80 }
81 } else if edge.is_rule_ref() {
82 rules.insert(edge.ref_rule_id());
83 } else if edge.is_repeat_ref() {
84 repeat_aux.insert(edge.aux_index());
85 }
86 }
87 }
88
89 let mut intervals: Vec<(i32, i32)> = Vec::new();
91 let mut last: i32 = -1;
92 for &end in &interval_ends {
93 if last == -1 {
94 last = end;
95 continue;
96 }
97 let ok = (last..end).all(|i| allowed[i as usize]);
98 if ok {
99 intervals.push((last, end - 1));
100 }
101 last = end;
102 }
103
104 for (lo, hi) in intervals {
105 let mut next_closure: AHashSet<i32> = AHashSet::new();
106 for &state in &closures[now_process] {
107 for edge in self.fsm.edges(state as usize) {
108 if edge.is_char_range()
109 && lo >= edge.min as i32
110 && hi <= edge.max as i32
111 && !next_closure.contains(&edge.target)
112 {
113 let mut ec: AHashSet<i32> = AHashSet::from_iter([edge.target]);
114 self.fsm.epsilon_closure(&mut ec);
115 next_closure.extend(ec);
116 }
117 }
118 }
119 let idx = closures.iter().position(|c| *c == next_closure);
120 match idx {
121 Some(j) => dfa.fsm_mut().add_edge(now_process, j, lo as i16, hi as i16),
122 None => {
123 dfa.fsm_mut()
124 .add_edge(now_process, closures.len(), lo as i16, hi as i16);
125 closures.push(next_closure);
126 }
127 }
128 }
129
130 for rule in &rules {
131 let next_closure = self.rule_target_closure(&closures[now_process], *rule);
132 let idx = closures.iter().position(|c| *c == next_closure);
133 match idx {
134 Some(j) => dfa.fsm_mut().add_rule_edge(now_process, j, *rule as i16),
135 None => {
136 dfa.fsm_mut()
137 .add_rule_edge(now_process, closures.len(), *rule as i16);
138 closures.push(next_closure);
139 }
140 }
141 }
142
143 for aux_idx in &repeat_aux {
144 let next_closure = self.repeat_target_closure(&closures[now_process], *aux_idx);
145 let idx = closures.iter().position(|c| *c == next_closure);
146 match idx {
147 Some(j) => dfa.fsm_mut().add_typed_edge(
148 now_process,
149 j,
150 edge_type::REPEAT_REF,
151 *aux_idx,
152 ),
153 None => {
154 dfa.fsm_mut().add_typed_edge(
155 now_process,
156 closures.len(),
157 edge_type::REPEAT_REF,
158 *aux_idx,
159 );
160 closures.push(next_closure);
161 }
162 }
163 }
164 now_process += 1;
165 }
166 dfa.fsm_mut()
167 .set_edge_aux_data(self.fsm.edge_aux_data().to_vec());
168 dfa.is_dfa = true;
169 Ok(dfa)
170 }
171
172 fn rule_target_closure(&self, from: &AHashSet<i32>, rule: i32) -> AHashSet<i32> {
174 let mut next: AHashSet<i32> = AHashSet::new();
175 for &state in from {
176 for edge in self.fsm.edges(state as usize) {
177 if edge.is_rule_ref() && edge.ref_rule_id() == rule && !next.contains(&edge.target)
178 {
179 let mut ec: AHashSet<i32> = AHashSet::from_iter([edge.target]);
180 self.fsm.epsilon_closure(&mut ec);
181 next.extend(ec);
182 }
183 }
184 }
185 next
186 }
187
188 fn repeat_target_closure(&self, from: &AHashSet<i32>, aux_idx: i16) -> AHashSet<i32> {
190 let mut next: AHashSet<i32> = AHashSet::new();
191 for &state in from {
192 for edge in self.fsm.edges(state as usize) {
193 if edge.is_repeat_ref()
194 && edge.aux_index() == aux_idx
195 && !next.contains(&edge.target)
196 {
197 let mut ec: AHashSet<i32> = AHashSet::from_iter([edge.target]);
198 self.fsm.epsilon_closure(&mut ec);
199 next.extend(ec);
200 }
201 }
202 }
203 next
204 }
205}
206
207#[cfg(test)]
208#[path = "algorithms_tests.rs"]
209mod tests;