cfg_symbol_bit_matrix/
remap_symbols.rs1use std::cmp::Ordering;
4
5use cfg_symbol::SymbolSource;
6use log::trace;
7
8use cfg_grammar::{Cfg, CfgRule};
9use cfg_symbol::Symbol;
10use cfg_symbol::intern::Mapping;
11
12pub struct Remap<'a> {
14 grammar: &'a mut Cfg,
15 mapping: Mapping,
16}
17
18impl<'a> Remap<'a> {
19 pub fn new(grammar: &'a mut Cfg) -> Self {
21 let num_syms = grammar.num_syms();
22 Remap {
23 grammar,
24 mapping: Mapping {
25 to_internal: SymbolSource::generate_fresh()
26 .take(num_syms)
27 .map(Some)
28 .collect(),
29 to_external: SymbolSource::generate_fresh().take(num_syms).collect(),
30 },
31 }
32 }
33
34 pub fn remove_unused_symbols(&mut self) {
36 let unused_symbols = self.grammar.unused_symbols();
37 self.reorder_symbols(|sym0, sym1| unused_symbols[sym0].cmp(&unused_symbols[sym1]));
38 let num_syms = self.grammar.num_syms();
39 self.grammar
40 .sym_source_mut()
41 .truncate(num_syms - unused_symbols.iter().count());
42 }
43
44 pub fn reorder_symbols<F>(&mut self, f: F)
47 where
48 F: Fn(Symbol, Symbol) -> Ordering,
49 {
50 let mut new_mapping = Mapping::new(self.grammar.num_syms());
52 new_mapping.to_external = SymbolSource::generate_fresh()
53 .take(self.grammar.num_syms())
54 .collect();
55 new_mapping.to_external.sort_by(|&a, &b| f(a, b));
58 for (before, after) in new_mapping
60 .to_external
61 .iter()
62 .cloned()
63 .zip(SymbolSource::generate_fresh())
64 {
65 new_mapping.to_internal[before.usize()] = Some(after);
66 }
67 self.mapping.translate(&new_mapping);
68 self.remap_symbols(|sym| new_mapping.to_internal[sym.usize()].unwrap());
69 }
70
71 pub fn remap_symbols<F>(&mut self, mut map: F)
75 where
76 F: FnMut(Symbol) -> Symbol,
77 {
78 let mut added_rules = vec![];
79 self.grammar.retain(|rule| {
80 trace!(
81 "REMAP {:?} -> {:?} ::= {:?} -> {:?}",
82 rule.lhs,
83 map(rule.lhs),
84 rule.rhs,
85 rule.rhs.iter().map(|&sym| map(sym)).collect::<Vec<_>>()
86 );
87 if map(rule.lhs) == rule.lhs && rule.rhs.iter().all(|&sym| map(sym) == sym) {
88 true
89 } else {
90 added_rules.push(CfgRule {
91 lhs: map(rule.lhs),
92 rhs: rule.rhs.iter().cloned().map(&mut map).collect(),
93 history: rule.history,
94 });
95 false
96 }
97 });
98 for rule in added_rules {
99 self.grammar.add_rule(rule);
100 }
101
102 let roots: Vec<_> = self.grammar.roots().iter().copied().map(&mut map).collect();
116 self.grammar.set_roots(&roots[..]);
117 let wrapped_roots: Vec<_> = self
118 .grammar
119 .wrapped_roots()
120 .iter()
121 .copied()
122 .map(|mut wrapped_root| {
123 trace!(
124 "REMAP WRAPPED ROOT {:?}",
125 (
126 wrapped_root.inner_root,
127 wrapped_root.root,
128 wrapped_root.start_of_input,
129 wrapped_root.end_of_input
130 )
131 );
132 wrapped_root.inner_root = map(wrapped_root.inner_root);
133 wrapped_root.root = map(wrapped_root.root);
134 wrapped_root.start_of_input = map(wrapped_root.start_of_input);
135 wrapped_root.end_of_input = map(wrapped_root.end_of_input);
136 wrapped_root
137 })
138 .collect();
139 self.grammar.set_wrapped_roots(&wrapped_roots[..]);
140 self.grammar.sym_source_mut().remap_symbols(map);
141 }
142
143 pub fn get_mapping(self) -> Mapping {
145 self.mapping
146 }
147}
148
149pub trait CfgRemapSymbolsExt {
151 fn remap(&mut self) -> Remap<'_>;
153}
154
155impl CfgRemapSymbolsExt for Cfg {
156 fn remap(&mut self) -> Remap<'_> {
157 Remap::new(self)
158 }
159}