diff --git a/cli/src/generate/build_tables/build_parse_table.rs b/cli/src/generate/build_tables/build_parse_table.rs index b87cc3d0..792a8759 100644 --- a/cli/src/generate/build_tables/build_parse_table.rs +++ b/cli/src/generate/build_tables/build_parse_table.rs @@ -174,18 +174,12 @@ impl<'a> ParseTableBuilder<'a> { non_terminal_successors .entry(next_symbol) .or_insert_with(|| ParseItemSet::default()) - .entries - .entry(successor) - .or_insert_with(|| TokenSet::new()) - .insert_all(lookaheads); + .insert(successor, lookaheads); } else { terminal_successors .entry(next_symbol) .or_insert_with(|| ParseItemSet::default()) - .entries - .entry(successor) - .or_insert_with(|| TokenSet::new()) - .insert_all(lookaheads); + .insert(successor, lookaheads); } } else { let action = if item.is_augmented() { @@ -620,8 +614,8 @@ impl<'a> ParseTableBuilder<'a> { ) -> AuxiliarySymbolInfo { let parent_symbols = item_set .entries - .keys() - .filter_map(|item| { + .iter() + .filter_map(|(item, _)| { let variable_index = item.variable_index as usize; if item.symbol() == Some(symbol) && !self.syntax_grammar.variables[variable_index].is_auxiliary() diff --git a/cli/src/generate/build_tables/item.rs b/cli/src/generate/build_tables/item.rs index 279c5df6..0222ac21 100644 --- a/cli/src/generate/build_tables/item.rs +++ b/cli/src/generate/build_tables/item.rs @@ -3,7 +3,6 @@ use crate::generate::rules::Associativity; use crate::generate::rules::{Symbol, SymbolType}; use smallbitvec::SmallBitVec; use std::cmp::Ordering; -use std::collections::BTreeMap; use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; @@ -40,7 +39,7 @@ pub(crate) struct ParseItem<'a> { #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct ParseItemSet<'a> { - pub entries: BTreeMap, TokenSet>, + pub entries: Vec<(ParseItem<'a>, TokenSet)>, } pub(crate) struct ParseItemDisplay<'a>( @@ -227,15 +226,28 @@ impl<'a> ParseItemSet<'a> { pub fn with(elements: impl IntoIterator, TokenSet)>) -> Self { let mut result = Self::default(); for (item, lookaheads) in elements { - result.entries.insert(item, lookaheads); + result.insert(item, &lookaheads); } result } + pub fn insert(&mut self, item: ParseItem<'a>, lookaheads: &TokenSet) -> &mut TokenSet { + match self.entries.binary_search_by(|(i, _)| i.cmp(&item)) { + Err(i) => { + self.entries.insert(i, (item, lookaheads.clone())); + &mut self.entries[i].1 + }, + Ok(i) => { + self.entries[i].1.insert_all(lookaheads); + &mut self.entries[i].1 + } + } + } + pub fn hash_unfinished_items(&self, h: &mut impl Hasher) { let mut previous_variable_index = u32::MAX; let mut previous_step_index = u32::MAX; - for item in self.entries.keys() { + for (item, _) in self.entries.iter() { if item.step().is_none() && item.variable_index != previous_variable_index || item.step_index != previous_step_index { @@ -251,7 +263,7 @@ impl<'a> ParseItemSet<'a> { impl<'a> Default for ParseItemSet<'a> { fn default() -> Self { Self { - entries: BTreeMap::new(), + entries: Vec::new(), } } } diff --git a/cli/src/generate/build_tables/item_set_builder.rs b/cli/src/generate/build_tables/item_set_builder.rs index 56d7c7c4..b941b179 100644 --- a/cli/src/generate/build_tables/item_set_builder.rs +++ b/cli/src/generate/build_tables/item_set_builder.rs @@ -285,18 +285,14 @@ impl<'a> ParseItemSetBuilder<'a> { // Use the pre-computed *additions* to expand the non-terminal. for addition in &self.transitive_closure_additions[step.symbol.index] { - let lookaheads = set - .entries - .entry(addition.item) - .or_insert_with(|| TokenSet::new()); - lookaheads.insert_all(&addition.info.lookaheads); + let lookaheads = set.insert(addition.item, &addition.info.lookaheads); if addition.info.propagates_lookaheads { lookaheads.insert_all(following_tokens); } } } } - set.entries.insert(item, lookaheads.clone()); + set.insert(item, lookaheads); } }