Reorder parse states by descending symbol count
This commit is contained in:
parent
2430733ee8
commit
759c1d6e65
1 changed files with 34 additions and 0 deletions
|
|
@ -26,6 +26,7 @@ pub(crate) fn minimize_parse_table(
|
|||
minimizer.merge_compatible_states();
|
||||
minimizer.remove_unit_reductions();
|
||||
minimizer.remove_unused_states();
|
||||
minimizer.reorder_states_by_descending_size();
|
||||
}
|
||||
|
||||
struct Minimizer<'a> {
|
||||
|
|
@ -454,4 +455,37 @@ impl<'a> Minimizer<'a> {
|
|||
original_state_id += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn reorder_states_by_descending_size(&mut self) {
|
||||
// Get a mapping of old state index -> new_state_index
|
||||
let mut old_ids_by_new_id = (0..self.parse_table.states.len()).collect::<Vec<_>>();
|
||||
&old_ids_by_new_id.sort_unstable_by_key(|i| {
|
||||
// Don't changes states 0 (the error state) or 1 (the start state).
|
||||
if *i <= 1 {
|
||||
return *i as i64 - 1_000_000;
|
||||
}
|
||||
|
||||
// Reorder all the other states by descending symbol count.
|
||||
let state = &self.parse_table.states[*i];
|
||||
-((state.terminal_entries.len() + state.nonterminal_entries.len()) as i64)
|
||||
});
|
||||
|
||||
// Get the inverse mapping
|
||||
let mut new_ids_by_old_id = vec![0; old_ids_by_new_id.len()];
|
||||
for (id, old_id) in old_ids_by_new_id.iter().enumerate() {
|
||||
new_ids_by_old_id[*old_id] = id;
|
||||
}
|
||||
|
||||
// Reorder the parse states and update their references to reflect
|
||||
// the new ordering.
|
||||
self.parse_table.states = old_ids_by_new_id
|
||||
.iter()
|
||||
.map(|old_id| {
|
||||
let mut state = ParseState::default();
|
||||
mem::swap(&mut state, &mut self.parse_table.states[*old_id]);
|
||||
state.update_referenced_states(|id, _| new_ids_by_old_id[id]);
|
||||
state
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue