1use std::fmt;
2use std::iter::Peekable;
3use std::sync::atomic::{AtomicU32, Ordering};
4
5use super::{Byte, Reference, Region, Tree, Type, Uninhabited};
6use crate::{Map, Set};
7
8#[cfg(test)]
9mod tests;
10
11#[derive(#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
::core::marker::StructuralPartialEq for Dfa<R, T> where R: Region, T: Type
{
}
#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
::core::cmp::PartialEq for Dfa<R, T> where R: Region, T: Type {
#[inline]
fn eq(&self, other: &Dfa<R, T>) -> bool {
self.transitions == other.transitions && self.start == other.start &&
self.accept == other.accept
}
}PartialEq)]
12#[cfg_attr(test, derive(Clone))]
13pub(crate) struct Dfa<R, T>
14where
15 R: Region,
16 T: Type,
17{
18 pub(crate) transitions: Map<State, Transitions<R, T>>,
19 pub(crate) start: State,
20 pub(crate) accept: State,
21}
22
23#[derive(#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
::core::marker::StructuralPartialEq for Transitions<R, T> where R: Region,
T: Type {
}
#[automatically_derived]
impl<R: ::core::cmp::PartialEq, T: ::core::cmp::PartialEq>
::core::cmp::PartialEq for Transitions<R, T> where R: Region, T: Type {
#[inline]
fn eq(&self, other: &Transitions<R, T>) -> bool {
self.byte_transitions == other.byte_transitions &&
self.ref_transitions == other.ref_transitions
}
}PartialEq, #[automatically_derived]
impl<R: ::core::clone::Clone, T: ::core::clone::Clone> ::core::clone::Clone
for Transitions<R, T> where R: Region, T: Type {
#[inline]
fn clone(&self) -> Transitions<R, T> {
Transitions {
byte_transitions: ::core::clone::Clone::clone(&self.byte_transitions),
ref_transitions: ::core::clone::Clone::clone(&self.ref_transitions),
}
}
}Clone, #[automatically_derived]
impl<R: ::core::fmt::Debug, T: ::core::fmt::Debug> ::core::fmt::Debug for
Transitions<R, T> where R: Region, T: Type {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Transitions",
"byte_transitions", &self.byte_transitions, "ref_transitions",
&&self.ref_transitions)
}
}Debug)]
24pub(crate) struct Transitions<R, T>
25where
26 R: Region,
27 T: Type,
28{
29 byte_transitions: EdgeSet<State>,
30 ref_transitions: Map<Reference<R, T>, State>,
31}
32
33impl<R, T> Default for Transitions<R, T>
34where
35 R: Region,
36 T: Type,
37{
38 fn default() -> Self {
39 Self { byte_transitions: EdgeSet::empty(), ref_transitions: Map::default() }
40 }
41}
42
43#[derive(#[automatically_derived]
impl ::core::hash::Hash for State {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Eq for State {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u32>;
}
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for State { }
#[automatically_derived]
impl ::core::cmp::PartialEq for State {
#[inline]
fn eq(&self, other: &State) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for State {
#[inline]
fn partial_cmp(&self, other: &State)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for State {
#[inline]
fn cmp(&self, other: &State) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::marker::Copy for State { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for State { }
#[automatically_derived]
impl ::core::clone::Clone for State {
#[inline]
fn clone(&self) -> State {
let _: ::core::clone::AssertParamIsClone<u32>;
*self
}
}Clone)]
47pub(crate) struct State(pub(crate) u32);
48
49impl State {
50 pub(crate) fn new() -> Self {
51 static COUNTER: AtomicU32 = AtomicU32::new(0);
52 Self(COUNTER.fetch_add(1, Ordering::SeqCst))
53 }
54}
55
56impl fmt::Debug for State {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 f.write_fmt(format_args!("S_{0}", self.0))write!(f, "S_{}", self.0)
59 }
60}
61
62impl<R, T> Dfa<R, T>
63where
64 R: Region,
65 T: Type,
66{
67 #[cfg(test)]
68 pub(crate) fn bool() -> Self {
69 Self::from_transitions(|accept| Transitions {
70 byte_transitions: EdgeSet::new(Byte::new(0x00..=0x01), accept),
71 ref_transitions: Map::default(),
72 })
73 }
74
75 pub(crate) fn unit() -> Self {
76 let transitions: Map<State, Transitions<R, T>> = Map::default();
77 let start = State::new();
78 let accept = start;
79
80 Self { transitions, start, accept }
81 }
82
83 pub(crate) fn from_byte(byte: Byte) -> Self {
84 Self::from_transitions(|accept| Transitions {
85 byte_transitions: EdgeSet::new(byte, accept),
86 ref_transitions: Map::default(),
87 })
88 }
89
90 pub(crate) fn from_ref(r: Reference<R, T>) -> Self {
91 Self::from_transitions(|accept| Transitions {
92 byte_transitions: EdgeSet::empty(),
93 ref_transitions: [(r, accept)].into_iter().collect(),
94 })
95 }
96
97 fn from_transitions(f: impl FnOnce(State) -> Transitions<R, T>) -> Self {
98 let start = State::new();
99 let accept = State::new();
100
101 Self { transitions: [(start, f(accept))].into_iter().collect(), start, accept }
102 }
103
104 pub(crate) fn from_tree(tree: Tree<!, R, T>) -> Result<Self, Uninhabited> {
105 Ok(match tree {
106 Tree::Byte(b) => Self::from_byte(b),
107 Tree::Ref(r) => Self::from_ref(r),
108 Tree::Alt(alts) => {
109 let mut alts = alts.into_iter().map(Self::from_tree).filter_map(Result::ok);
111 let dfa = alts.next().ok_or(Uninhabited)?;
113 alts.fold(dfa, |dfa, alt| dfa.union(alt, State::new))
115 }
116 Tree::Seq(elts) => {
117 let mut dfa = Self::unit();
118 for elt in elts.into_iter().map(Self::from_tree) {
119 dfa = dfa.concat(elt?);
120 }
121 dfa
122 }
123 })
124 }
125
126 pub(crate) fn concat(self, other: Self) -> Self {
128 if self.start == self.accept {
129 return other;
130 } else if other.start == other.accept {
131 return self;
132 }
133
134 let start = self.start;
135 let accept = other.accept;
136
137 let mut transitions: Map<State, Transitions<R, T>> = self.transitions;
138
139 for (source, transition) in other.transitions {
140 let fix_state = |state| if state == other.start { self.accept } else { state };
141 let byte_transitions = transition.byte_transitions.map_states(&fix_state);
142 let ref_transitions = transition
143 .ref_transitions
144 .into_iter()
145 .map(|(r, state)| (r, fix_state(state)))
146 .collect();
147
148 let old = transitions
149 .insert(fix_state(source), Transitions { byte_transitions, ref_transitions });
150 if !old.is_none() {
::core::panicking::panic("assertion failed: old.is_none()")
};assert!(old.is_none());
151 }
152
153 Self { transitions, start, accept }
154 }
155
156 pub(crate) fn union(self, other: Self, mut new_state: impl FnMut() -> State) -> Self {
158 let a = self;
164 let b = other;
165
166 let accept = new_state();
167
168 let mut mapping: Map<(Option<State>, Option<State>), State> = Map::default();
169
170 let mut mapped = |(a_state, b_state)| {
171 if Some(a.accept) == a_state || Some(b.accept) == b_state {
172 accept
175 } else {
176 *mapping.entry((a_state, b_state)).or_insert_with(&mut new_state)
177 }
178 };
179
180 let start = mapped((Some(a.start), Some(b.start)));
181 let mut transitions: Map<State, Transitions<R, T>> = Map::default();
182 let empty_transitions = Transitions::default();
183
184 struct WorkQueue {
185 queue: Vec<(Option<State>, Option<State>)>,
186 enqueued: Set<(Option<State>, Option<State>)>,
190 }
191 impl WorkQueue {
192 fn enqueue(&mut self, a_state: Option<State>, b_state: Option<State>) {
193 if self.enqueued.insert((a_state, b_state)) {
194 self.queue.push((a_state, b_state));
195 }
196 }
197 }
198 let mut queue = WorkQueue { queue: Vec::new(), enqueued: Set::default() };
199 queue.enqueue(Some(a.start), Some(b.start));
200
201 while let Some((a_src, b_src)) = queue.queue.pop() {
202 let src = mapped((a_src, b_src));
203 if src == accept {
204 continue;
216 }
217
218 let a_transitions =
219 a_src.and_then(|a_src| a.transitions.get(&a_src)).unwrap_or(&empty_transitions);
220 let b_transitions =
221 b_src.and_then(|b_src| b.transitions.get(&b_src)).unwrap_or(&empty_transitions);
222
223 let byte_transitions = a_transitions.byte_transitions.union(
224 &b_transitions.byte_transitions,
225 |a_dst, b_dst| {
226 if !(a_dst.is_some() || b_dst.is_some()) {
::core::panicking::panic("assertion failed: a_dst.is_some() || b_dst.is_some()")
};assert!(a_dst.is_some() || b_dst.is_some());
227
228 queue.enqueue(a_dst, b_dst);
229 mapped((a_dst, b_dst))
230 },
231 );
232
233 let ref_transitions =
234 a_transitions.ref_transitions.keys().chain(b_transitions.ref_transitions.keys());
235
236 let ref_transitions = ref_transitions
237 .map(|ref_transition| {
238 let a_dst = a_transitions.ref_transitions.get(ref_transition).copied();
239 let b_dst = b_transitions.ref_transitions.get(ref_transition).copied();
240
241 if !(a_dst.is_some() || b_dst.is_some()) {
::core::panicking::panic("assertion failed: a_dst.is_some() || b_dst.is_some()")
};assert!(a_dst.is_some() || b_dst.is_some());
242
243 queue.enqueue(a_dst, b_dst);
244 (*ref_transition, mapped((a_dst, b_dst)))
245 })
246 .collect();
247
248 let old = transitions.insert(src, Transitions { byte_transitions, ref_transitions });
249 {
match (&old, &None) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(old, None);
252 }
253
254 Self { transitions, start, accept }
255 }
256
257 pub(crate) fn get_uninit_edge_dst(&self, state: State) -> Option<State> {
258 let transitions = self.transitions.get(&state)?;
259 transitions.byte_transitions.get_uninit_edge_dst()
260 }
261
262 pub(crate) fn bytes_from(&self, start: State) -> impl Iterator<Item = (Byte, State)> {
263 self.transitions
264 .get(&start)
265 .map(|transitions| transitions.byte_transitions.iter())
266 .into_flat_iter()
267 }
268
269 pub(crate) fn refs_from(&self, start: State) -> impl Iterator<Item = (Reference<R, T>, State)> {
270 self.transitions
271 .get(&start)
272 .map(|transitions| transitions.ref_transitions.iter())
273 .into_flat_iter()
274 .map(|(r, s)| (*r, *s))
275 }
276
277 #[cfg(test)]
278 pub(crate) fn from_edges<B: Clone + Into<Byte>>(
279 start: u32,
280 accept: u32,
281 edges: &[(u32, B, u32)],
282 ) -> Self {
283 let start = State(start);
284 let accept = State(accept);
285 let mut transitions: Map<State, Vec<(Byte, State)>> = Map::default();
286
287 for &(src, ref edge, dst) in edges.iter() {
288 transitions.entry(State(src)).or_default().push((edge.clone().into(), State(dst)));
289 }
290
291 let transitions = transitions
292 .into_iter()
293 .map(|(src, edges)| {
294 (
295 src,
296 Transitions {
297 byte_transitions: EdgeSet::from_edges(edges),
298 ref_transitions: Map::default(),
299 },
300 )
301 })
302 .collect();
303
304 Self { start, accept, transitions }
305 }
306}
307
308impl<R, T> fmt::Debug for Dfa<R, T>
310where
311 R: Region,
312 T: Type,
313{
314 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315 f.write_fmt(format_args!("digraph {{\n"))writeln!(f, "digraph {{")?;
316 f.write_fmt(format_args!(" start [shape = point, style = invis]\n"))writeln!(f, " start [shape = point, style = invis]")?;
317 f.write_fmt(format_args!(" start -> {0:?}\n", self.start))writeln!(f, " start -> {:?}", self.start)?;
318 f.write_fmt(format_args!(" {0:?} [shape = doublecircle]\n", self.accept))writeln!(f, " {:?} [shape = doublecircle]", self.accept)?;
319
320 for (src, transitions) in self.transitions.iter() {
321 for (t, dst) in transitions.byte_transitions.iter() {
322 f.write_fmt(format_args!(" {0:?} -> {1:?} [label=\"{2:?}\"]\n", src, dst,
t))writeln!(f, " {src:?} -> {dst:?} [label=\"{t:?}\"]")?;
323 }
324
325 for (t, dst) in transitions.ref_transitions.iter() {
326 f.write_fmt(format_args!(" {0:?} -> {1:?} [label=\"{2:?}\"]\n", src, dst,
t))writeln!(f, " {src:?} -> {dst:?} [label=\"{t:?}\"]")?;
327 }
328 }
329
330 f.write_fmt(format_args!("}}\n"))writeln!(f, "}}")
331 }
332}
333
334use edge_set::EdgeSet;
335mod edge_set {
336 use smallvec::SmallVec;
337
338 use super::*;
339
340 #[derive(#[automatically_derived]
impl<S: ::core::cmp::Eq> ::core::cmp::Eq for EdgeSet<S> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<SmallVec<[(Byte, S); 1]>>;
}
}Eq, #[automatically_derived]
impl<S: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
EdgeSet<S> {
}
#[automatically_derived]
impl<S: ::core::cmp::PartialEq> ::core::cmp::PartialEq for EdgeSet<S> {
#[inline]
fn eq(&self, other: &EdgeSet<S>) -> bool { self.runs == other.runs }
}PartialEq, #[automatically_derived]
impl<S: ::core::clone::Clone> ::core::clone::Clone for EdgeSet<S> {
#[inline]
fn clone(&self) -> EdgeSet<S> {
EdgeSet { runs: ::core::clone::Clone::clone(&self.runs) }
}
}Clone, #[automatically_derived]
impl<S: ::core::fmt::Debug> ::core::fmt::Debug for EdgeSet<S> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "EdgeSet",
"runs", &&self.runs)
}
}Debug)]
342 pub(super) struct EdgeSet<S = State> {
343 runs: SmallVec<[(Byte, S); 1]>,
348 }
349
350 impl<S> EdgeSet<S> {
351 pub(crate) fn new(range: Byte, dst: S) -> Self {
352 let mut this = Self { runs: SmallVec::new() };
353 if !range.is_empty() {
354 this.runs.push((range, dst));
355 }
356 this
357 }
358
359 pub(crate) fn empty() -> Self {
360 Self { runs: SmallVec::new() }
361 }
362
363 #[cfg(test)]
364 pub(crate) fn from_edges(mut edges: Vec<(Byte, S)>) -> Self
365 where
366 S: Ord,
367 {
368 edges.sort();
369 Self { runs: edges.into() }
370 }
371
372 pub(crate) fn iter(&self) -> impl Iterator<Item = (Byte, S)>
373 where
374 S: Copy,
375 {
376 self.runs.iter().copied()
377 }
378
379 pub(crate) fn get_uninit_edge_dst(&self) -> Option<S>
380 where
381 S: Copy,
382 {
383 let &(range, dst) = self.runs.last()?;
385 if range.contains_uninit() { Some(dst) } else { None }
386 }
387
388 pub(crate) fn map_states<SS>(self, mut f: impl FnMut(S) -> SS) -> EdgeSet<SS> {
389 EdgeSet { runs: self.runs.into_iter().map(|(b, s)| (b, f(s))).collect() }
390 }
391
392 pub(crate) fn union(
402 &self,
403 other: &Self,
404 mut join: impl FnMut(Option<S>, Option<S>) -> S,
405 ) -> EdgeSet<S>
406 where
407 S: Copy + Eq,
408 {
409 let mut runs: SmallVec<[(Byte, S); 1]> = SmallVec::new();
410 let xs = self.runs.iter().copied();
411 let ys = other.runs.iter().copied();
412 for (range, (x, y)) in union(xs, ys) {
413 let state = join(x, y);
414 match runs.last_mut() {
415 Some(&mut (ref mut last_range, ref mut last_state))
417 if last_range.end == range.start && *last_state == state =>
418 {
419 last_range.end = range.end
420 }
421 _ => runs.push((range, state)),
422 }
423 }
424 EdgeSet { runs }
425 }
426 }
427}
428
429pub(crate) fn union<S: Copy, X: Iterator<Item = (Byte, S)>, Y: Iterator<Item = (Byte, S)>>(
437 xs: X,
438 ys: Y,
439) -> UnionIter<X, Y> {
440 UnionIter { xs: xs.peekable(), ys: ys.peekable() }
441}
442
443pub(crate) struct UnionIter<X: Iterator, Y: Iterator> {
444 xs: Peekable<X>,
445 ys: Peekable<Y>,
446}
447
448impl<S: Copy, X: Iterator<Item = (Byte, S)>, Y: Iterator<Item = (Byte, S)>> Iterator
450 for UnionIter<X, Y>
451{
452 type Item = (Byte, (Option<S>, Option<S>));
453
454 fn next(&mut self) -> Option<Self::Item> {
455 use std::cmp::{self, Ordering};
456
457 let ret;
458 match (self.xs.peek_mut(), self.ys.peek_mut()) {
459 (None, None) => {
460 ret = None;
461 }
462 (Some(x), None) => {
463 ret = Some((x.0, (Some(x.1), None)));
464 self.xs.next();
465 }
466 (None, Some(y)) => {
467 ret = Some((y.0, (None, Some(y.1))));
468 self.ys.next();
469 }
470 (Some(x), Some(y)) => {
471 let start;
472 let end;
473 let dst;
474 match x.0.start.cmp(&y.0.start) {
475 Ordering::Less => {
476 start = x.0.start;
477 end = cmp::min(x.0.end, y.0.start);
478 dst = (Some(x.1), None);
479 }
480 Ordering::Greater => {
481 start = y.0.start;
482 end = cmp::min(x.0.start, y.0.end);
483 dst = (None, Some(y.1));
484 }
485 Ordering::Equal => {
486 start = x.0.start;
487 end = cmp::min(x.0.end, y.0.end);
488 dst = (Some(x.1), Some(y.1));
489 }
490 }
491 ret = Some((Byte { start, end }, dst));
492 if start == x.0.start {
493 x.0.start = end;
494 }
495 if start == y.0.start {
496 y.0.start = end;
497 }
498 if x.0.is_empty() {
499 self.xs.next();
500 }
501 if y.0.is_empty() {
502 self.ys.next();
503 }
504 }
505 }
506 ret
507 }
508}