1use std::collections::hash_map::Entry;
6use std::collections::HashMap;
7
8use crate::builder::SequenceRuleBuilder;
9use crate::destination::SequenceDestination;
10use crate::Separator::{self, Liberal, Proper, Trailing};
11use crate::Sequence;
12use crate::Symbol;
13use cfg_grammar::history::node::{HistoryId, HistoryNodeRewriteSequence, RootHistoryNode};
14use cfg_grammar::rule::builder::RuleBuilder;
15use cfg_grammar::rule_container::RuleContainer;
16
17pub struct SequencesToProductions<'a, D>
19where
20 D: RuleContainer,
21{
22 destination: &'a mut D,
23 stack: Vec<Sequence>,
24 map: HashMap<PartialSequence, Symbol>,
25 top: Option<HistoryId>,
26 lhs: Option<Symbol>,
27}
28
29#[derive(Clone, Debug, Eq, Hash, PartialEq)]
31struct PartialSequence {
32 rhs: Symbol,
33 start: u32,
34 end: Option<u32>,
35 separator: Separator,
36}
37
38impl<'a, D> SequenceDestination for SequencesToProductions<'a, D>
39where
40 D: RuleContainer,
41{
42 fn add_sequence(&mut self, seq: Sequence) {
43 self.rewrite(seq);
44 }
45}
46
47impl From<Sequence> for PartialSequence {
48 fn from(value: Sequence) -> Self {
49 PartialSequence {
50 rhs: value.rhs,
51 start: value.start,
52 end: value.end,
53 separator: value.separator,
54 }
55 }
56}
57
58impl<'a, D> SequencesToProductions<'a, D>
59where
60 D: RuleContainer,
61{
62 pub fn new(destination: &'a mut D) -> Self {
64 SequencesToProductions {
65 destination,
66 stack: vec![],
67 map: HashMap::new(),
68 top: None,
69 lhs: None,
70 }
71 }
72
73 pub fn rewrite_sequences(sequence_rules: &[Sequence], rule_container: &'a mut D) {
75 let sequences = SequencesToProductions::new(rule_container);
76 let mut rewrite = SequenceRuleBuilder::new(sequences);
77 for rule in sequence_rules {
78 rewrite = rewrite
79 .sequence(rule.lhs)
80 .separator(rule.separator)
81 .inclusive(rule.start, rule.end)
82 .rhs_with_history(rule.rhs, rule.history_id);
83 }
84 }
85
86 pub fn rewrite(&mut self, top: Sequence) {
88 self.stack.clear();
89 self.map.clear();
90 let prev = top.history_id.unwrap_or_else(|| {
91 self.destination
92 .add_history_node(RootHistoryNode::NoOp.into())
93 });
94 let history_id_top = self.destination.add_history_node(
95 HistoryNodeRewriteSequence {
96 top: true,
97 rhs: top.rhs,
98 sep: top.separator.into(),
99 prev,
100 }
101 .into(),
102 );
103 self.top = Some(history_id_top);
104 self.reduce(top);
105 let prev = top.history_id.unwrap_or_else(|| {
106 self.destination
107 .add_history_node(RootHistoryNode::NoOp.into())
108 });
109 let history_id_bottom = self.destination.add_history_node(
110 HistoryNodeRewriteSequence {
111 top: false,
112 rhs: top.rhs,
113 sep: top.separator.into(),
114 prev,
115 }
116 .into(),
117 );
118 *self.top.as_mut().unwrap() = history_id_bottom;
119 while let Some(seq) = self.stack.pop() {
120 assert!(seq.start <= seq.end.unwrap_or(!0));
121 self.reduce(seq);
122 }
123 }
124
125 fn recurse(&mut self, seq: &Sequence) -> Symbol {
126 let sym_source = &mut self.destination;
127 let partial: PartialSequence = (*seq).into();
129
130 match self.map.entry(partial) {
131 Entry::Vacant(vacant) => {
132 let lhs = sym_source.next_sym();
133 vacant.insert(lhs);
134 self.stack.push(Sequence { lhs, ..*seq });
135 lhs
136 }
137 Entry::Occupied(lhs) => *lhs.get(),
138 }
139 }
140
141 fn rhs<A: AsRef<[Symbol]>>(&mut self, rhs: A) {
142 RuleBuilder::new(&mut self.destination)
143 .rule(self.lhs.unwrap())
144 .history(self.top.unwrap())
145 .rhs(rhs);
146 }
147
148 fn reduce(&mut self, sequence: Sequence) {
149 let Sequence {
150 lhs,
151 rhs,
152 start,
153 end,
154 separator,
155 ..
156 } = sequence;
157 self.lhs = Some(lhs);
158 match (separator, start, end) {
160 (Liberal(sep), _, _) => {
161 let sym1 = self.recurse(&sequence.clone().separator(Proper(sep)));
162 let sym2 = self.recurse(&sequence.clone().separator(Trailing(sep)));
163 self.rhs([sym1]);
165 self.rhs([sym2]);
166 }
167 (_, 0, Some(0)) => {
168 self.rhs([]);
170 }
171 (_, 0, end) => {
172 self.rhs([]);
174 let sym = self.recurse(&sequence.inclusive(1, end));
175 self.rhs([sym]);
176 }
177 (Trailing(sep), _, _) => {
178 let sym = self.recurse(&sequence.separator(Proper(sep)));
179 self.rhs([sym, sep]);
181 }
182 (_, 1, None) => {
183 self.rhs([rhs]);
186 if let Proper(sep) = separator {
189 self.rhs([lhs, sep, rhs]);
190 } else {
191 self.rhs([lhs, rhs]);
192 }
193 }
194 (_, 1, Some(1)) => {
195 self.rhs([rhs]);
196 }
197 (_, 1, Some(2)) => {
198 let sym1 = self.recurse(&sequence.clone().range(1..=1));
199 let sym2 = self.recurse(&sequence.clone().range(2..=2));
200 self.rhs([sym1]);
202 self.rhs([sym2]);
203 }
204 (_, 1, Some(end)) => {
205 let pow2 = end.next_power_of_two() / 2;
207 let (seq1, block, seq2) = (
208 sequence.clone().range(1..=pow2),
209 sequence.clone().range(pow2..=pow2),
210 sequence.clone().range(1..=end - pow2),
211 );
212 let rhs1 = self.recurse(&seq1);
213 let block = self.recurse(&block.separator(separator.prefix_separator()));
214 let rhs2 = self.recurse(&seq2);
215 self.rhs([rhs1]);
217 self.rhs([block, rhs2]);
218 }
219 (Proper(sep), 2, Some(2)) => {
220 self.rhs([rhs, sep, rhs]);
221 }
222 (_, 2, Some(2)) => {
223 self.rhs([rhs, rhs]);
224 }
225 (_, 2.., end) => {
226 let (seq1, seq2) = if Some(start) == end {
228 let pow2 = start.next_power_of_two() / 2;
230 (
231 sequence.clone().range(pow2..=pow2),
232 sequence.clone().range(start - pow2..=start - pow2),
233 )
234 } else {
235 (
237 sequence.clone().range(start - 1..=start - 1),
238 sequence
239 .clone()
240 .inclusive(1, end.map(|end| end - start + 1)),
241 )
242 };
243 let (rhs1, rhs2) = (
244 self.recurse(&seq1.separator(separator.prefix_separator())),
245 self.recurse(&seq2.separator(separator)),
246 );
247 self.rhs([rhs1, rhs2]);
249 }
250 }
251 }
252}