1use std::collections::HashMap;
6use std::collections::hash_map::Entry;
7
8use crate::Separator::{self, Liberal, Proper, Trailing};
9use crate::Sequence;
10use crate::Symbol;
11use crate::destination::SequenceDestination;
12use cfg_grammar::Cfg;
13use cfg_grammar::rule_builder::RuleBuilder;
14use cfg_history::{
15 HistoryNodeRewriteSequence, HistoryNodeSequenceRhs, RootHistoryNode, earley::History,
16};
17
18pub struct SequencesToProductions<'a> {
20 destination: &'a mut Cfg,
21 stack: Vec<Sequence>,
22 map: HashMap<PartialSequence, Symbol>,
23 top: Option<History>,
24 lhs: Option<Symbol>,
25}
26
27#[derive(Clone, Debug, Eq, Hash, PartialEq)]
29struct PartialSequence {
30 rhs: Symbol,
31 start: u32,
32 end: Option<u32>,
33 separator: Separator,
34}
35
36impl<'a> SequenceDestination for SequencesToProductions<'a> {
37 fn add_sequence(&mut self, seq: Sequence) {
38 self.rewrite(seq);
39 }
40}
41
42impl From<Sequence> for PartialSequence {
43 fn from(value: Sequence) -> Self {
44 PartialSequence {
45 rhs: value.rhs,
46 start: value.start,
47 end: value.end,
48 separator: value.separator,
49 }
50 }
51}
52
53impl<'a> SequencesToProductions<'a> {
54 pub fn new(destination: &'a mut Cfg) -> Self {
56 SequencesToProductions {
57 destination,
58 stack: vec![],
59 map: HashMap::new(),
60 top: None,
61 lhs: None,
62 }
63 }
64
65 pub fn rewrite(&mut self, top: Sequence) {
67 self.stack.clear();
68 self.map.clear();
69 let prev = top
70 .history
71 .unwrap_or_else(|| RootHistoryNode::Rule { lhs: top.lhs }.into());
72 let history_top = Into::into(HistoryNodeRewriteSequence {
73 top: true,
74 rhs: top.rhs,
75 sep: top.separator.into(),
76 prev,
77 });
78 self.top = Some(history_top);
79 self.reduce(top);
80 let prev = top.history.unwrap_or_else(|| RootHistoryNode::NoOp.into());
81 let history_bottom = Into::into(HistoryNodeRewriteSequence {
82 top: false,
83 rhs: top.rhs,
84 sep: top.separator.into(),
85 prev,
86 });
87 *self.top.as_mut().unwrap() = history_bottom;
88 while let Some(seq) = self.stack.pop() {
89 assert!(seq.start <= seq.end.unwrap_or(!0));
90 self.reduce(seq);
91 }
92 }
93
94 fn recurse(&mut self, seq: &Sequence) -> Symbol {
95 let sym_source = &mut self.destination;
96 let partial: PartialSequence = (*seq).into();
98
99 match self.map.entry(partial) {
100 Entry::Vacant(vacant) => {
101 let lhs = sym_source.next_sym(None);
102 vacant.insert(lhs);
103 self.stack.push(Sequence { lhs, ..*seq });
104 lhs
105 }
106 Entry::Occupied(lhs) => *lhs.get(),
107 }
108 }
109
110 fn rhs<A: AsRef<[Symbol]>>(&mut self, rhs: A) {
111 assert!(rhs.as_ref().len() <= 3);
112 let history = Into::into(HistoryNodeSequenceRhs {
113 prev: self.top.unwrap(),
114 rhs: [
115 rhs.as_ref().get(0).copied(),
116 rhs.as_ref().get(1).copied(),
117 rhs.as_ref().get(2).copied(),
118 ],
119 });
120 RuleBuilder::new(self.destination)
121 .rule(self.lhs.unwrap())
122 .history(history)
123 .rhs(rhs);
124 }
125
126 fn reduce(&mut self, sequence: Sequence) {
127 let Sequence {
128 lhs,
129 rhs,
130 start,
131 end,
132 separator,
133 ..
134 } = sequence;
135 self.lhs = Some(lhs);
136 match (separator, start, end) {
138 (Liberal(sep), _, _) => {
139 let sym1 = self.recurse(&sequence.separator(Proper(sep)));
140 let sym2 = self.recurse(&sequence.separator(Trailing(sep)));
141 self.rhs([sym1]);
143 self.rhs([sym2]);
144 }
145 (_, 0, Some(0)) => {
146 self.rhs([]);
148 }
149 (_, 0, end) => {
150 self.rhs([]);
152 let sym = self.recurse(&sequence.inclusive(1, end));
153 self.rhs([sym]);
154 }
155 (Trailing(sep), _, _) => {
156 let sym = self.recurse(&sequence.separator(Proper(sep)));
157 self.rhs([sym, sep]);
159 }
160 (_, 1, None) => {
161 self.rhs([rhs]);
164 if let Proper(sep) = separator {
167 self.rhs([lhs, sep, rhs]);
168 } else {
169 self.rhs([lhs, rhs]);
170 }
171 }
172 (_, 1, Some(1)) => {
173 self.rhs([rhs]);
174 }
175 (_, 1, Some(2)) => {
176 let sym1 = self.recurse(&sequence.range(1..=1));
177 let sym2 = self.recurse(&sequence.range(2..=2));
178 self.rhs([sym1]);
180 self.rhs([sym2]);
181 }
182 (_, 1, Some(end)) => {
183 let pow2 = end.next_power_of_two() / 2;
185 let (seq1, block, seq2) = (
186 sequence.range(1..=pow2),
187 sequence.range(pow2..=pow2),
188 sequence.range(1..=end - pow2),
189 );
190 let rhs1 = self.recurse(&seq1);
191 let block = self.recurse(&block.separator(separator.prefix_separator()));
192 let rhs2 = self.recurse(&seq2);
193 self.rhs([rhs1]);
195 self.rhs([block, rhs2]);
196 }
197 (Proper(sep), 2, Some(2)) => {
198 self.rhs([rhs, sep, rhs]);
199 }
200 (_, 2, Some(2)) => {
201 self.rhs([rhs, rhs]);
202 }
203 (_, 2.., end) => {
204 let (seq1, seq2) = if Some(start) == end {
206 let pow2 = start.next_power_of_two() / 2;
208 (
209 sequence.range(pow2..=pow2),
210 sequence.range(start - pow2..=start - pow2),
211 )
212 } else {
213 (
215 sequence.range(start - 1..=start - 1),
216 sequence.inclusive(1, end.map(|end| end - start + 1)),
217 )
218 };
219 let (rhs1, rhs2) = (
220 self.recurse(&seq1.separator(separator.prefix_separator())),
221 self.recurse(&seq2.separator(separator)),
222 );
223 self.rhs([rhs1, rhs2]);
225 }
226 }
227 }
228}