1use alloc::boxed::Box;
2use alloc::string::String;
3use alloc::vec::Vec;
4use serde::Serialize;
5use std::mem;
6use string_interner::symbol::SymbolU32;
7
8#[derive(Debug, Clone, Serialize)]
9pub enum Node {
10 Terminal(String),
11 RegexString(String),
12 Nonterminal(String),
13 Multiple(Vec<Node>),
14 RegexExt(Box<Node>, RegexExtKind),
15 Symbol(Box<Node>, SymbolKind, Box<Node>),
16 Group(Box<Node>),
17 EarlyEndRegexString(String),
18 Substrings(String),
19 RegexComplement(String),
20}
21
22impl Drop for Node {
23 fn drop(&mut self) {
24 let mut stack = vec![];
25 match self {
26 Node::Terminal(_) | Node::RegexString(_) | Node::Nonterminal(_) | Node::RegexComplement(_) => {}
27 Node::Multiple(nodes) => {
28 while let Some(node) = nodes.pop() {
29 stack.push(node);
30 }
31 }
32 Node::RegexExt(node, _) => {
33 let node = mem::replace(node.as_mut(), Node::Terminal(String::new()));
34 stack.push(node);
35 }
36 Node::Symbol(lhs, _, rhs) => {
37 let lhs = mem::replace(lhs.as_mut(), Node::Terminal(String::new()));
38 let rhs = mem::replace(rhs.as_mut(), Node::Terminal(String::new()));
39 stack.push(lhs);
40 stack.push(rhs);
41 }
42 Node::Group(node) => {
43 let node = mem::replace(node.as_mut(), Node::Terminal(String::new()));
44 stack.push(node);
45 }
46 Node::EarlyEndRegexString(_) => {}
47 Node::Substrings(_) => {}
48 };
49 while let Some(mut node) = stack.pop() {
50 match &mut node {
51 Node::Multiple(nodes) => {
52 while let Some(node) = nodes.pop() {
53 stack.push(node);
54 }
55 }
56 Node::RegexExt(node, _) => {
57 let node = mem::replace(node.as_mut(), Node::Terminal(String::new()));
58 stack.push(node);
59 }
60 Node::Symbol(lhs, _, rhs) => {
61 let lhs = mem::replace(lhs.as_mut(), Node::Terminal(String::new()));
62 let rhs = mem::replace(rhs.as_mut(), Node::Terminal(String::new()));
63 stack.push(lhs);
64 stack.push(rhs);
65 }
66 Node::Group(node) => {
67 let node = mem::replace(node.as_mut(), Node::Terminal(String::new()));
68 stack.push(node);
69 }
70 _ => {}
71 }
72 }
73 }
74}
75#[allow(clippy::upper_case_acronyms)]
76#[derive(Debug, Clone)]
77pub enum NodeWithID {
78 Terminal(SymbolU32),
79 RegexString(SymbolU32),
80 Nonterminal(SymbolU32),
81 Multiple(Vec<NodeWithID>),
82 RegexExt(Box<NodeWithID>, RegexExtKind),
83 Symbol(Box<NodeWithID>, SymbolKind, Box<NodeWithID>),
84 Group(Box<NodeWithID>),
85 EarlyEndRegexString(SymbolU32),
86 Substrings(SymbolU32),
87 RegexComplement(SymbolU32),
88 Unknown,
89}
90
91impl Drop for NodeWithID {
92 fn drop(&mut self) {
93 let mut stack = vec![];
94 match self {
95 NodeWithID::Terminal(_) | NodeWithID::RegexString(_) | NodeWithID::Nonterminal(_) | NodeWithID::RegexComplement(_) => {}
96 NodeWithID::Multiple(nodes) => {
97 while let Some(node) = nodes.pop() {
98 stack.push(node);
99 }
100 }
101 NodeWithID::RegexExt(node, _) => {
102 let node = mem::replace(node.as_mut(), NodeWithID::Unknown);
103 stack.push(node);
104 }
105 NodeWithID::Symbol(lhs, _, rhs) => {
106 let lhs = mem::replace(lhs.as_mut(), NodeWithID::Unknown);
107 let rhs = mem::replace(rhs.as_mut(), NodeWithID::Unknown);
108 stack.push(lhs);
109 stack.push(rhs);
110 }
111 NodeWithID::Group(node) => {
112 let node = mem::replace(node.as_mut(), NodeWithID::Unknown);
113 stack.push(node);
114 }
115 NodeWithID::EarlyEndRegexString(_) => {}
116 NodeWithID::Substrings(_) => {}
117 NodeWithID::Unknown => {}
118 };
119 while let Some(mut node) = stack.pop() {
120 match &mut node {
121 NodeWithID::Multiple(nodes) => {
122 while let Some(node) = nodes.pop() {
123 stack.push(node);
124 }
125 }
126 NodeWithID::RegexExt(node, _) => {
127 let node = mem::replace(node.as_mut(), NodeWithID::Unknown);
128 stack.push(node);
129 }
130 NodeWithID::Symbol(lhs, _, rhs) => {
131 let lhs = mem::replace(lhs.as_mut(), NodeWithID::Unknown);
132 let rhs = mem::replace(rhs.as_mut(), NodeWithID::Unknown);
133 stack.push(lhs);
134 stack.push(rhs);
135 }
136 NodeWithID::Group(node) => {
137 let node = mem::replace(node.as_mut(), NodeWithID::Unknown);
138 stack.push(node);
139 }
140 _ => {}
141 }
142 }
143 }
144}
145
146#[allow(clippy::upper_case_acronyms)]
147#[derive(Debug, Clone)]
148pub(crate) enum NoNestingNode {
149 Unknown,
150 Terminal(SymbolU32),
151 RegexString(SymbolU32),
152 Nonterminal(SymbolU32),
153 RegexComplement(SymbolU32),
154 Concatenations(Vec<NoNestingNode>),
155 Alternations(Vec<NoNestingNode>),
156 EarlyEndRegexString(SymbolU32),
157 Substrings(SymbolU32),
158}
159#[allow(clippy::upper_case_acronyms)]
160#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
161pub enum OperatorFlattenedNode {
162 Terminal(SymbolU32),
163 RegexString(SymbolU32),
164 Nonterminal(SymbolU32),
165 EarlyEndRegexString(SymbolU32),
166 Substrings(SymbolU32),
167 RegexComplement(SymbolU32),
168}
169#[derive(Debug, Clone, Hash, Eq, PartialEq)]
170pub struct Rhs {
171 pub alternations: Vec<Alternation>,
172}
173#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
174pub struct Alternation {
175 pub concatenations: Vec<OperatorFlattenedNode>,
176}
177#[derive(Debug, Clone, Serialize, Copy, PartialEq, Eq, Hash)]
178pub enum RegexExtKind {
179 Repeat0,
180 Repeat1,
181 Optional,
182}
183
184#[derive(Debug, Clone, Serialize, Copy)]
185pub enum SymbolKind {
186 Concatenation,
187 Alternation,
188}