diff --git a/cli/src/generate/render.rs b/cli/src/generate/render.rs index 78a07a22..613776bf 100644 --- a/cli/src/generate/render.rs +++ b/cli/src/generate/render.rs @@ -1057,7 +1057,7 @@ impl Generator { } fn add_parse_table(&mut self) { - let mut parse_table_entries = Vec::new(); + let mut parse_table_entries = HashMap::new(); let mut next_parse_action_list_index = 0; self.get_parse_action_list_id( @@ -1224,6 +1224,11 @@ impl Generator { add_line!(self, ""); } + let mut parse_table_entries: Vec<_> = parse_table_entries + .into_iter() + .map(|(entry, i)| (i, entry)) + .collect(); + parse_table_entries.sort_by_key(|(index, _)| *index); self.add_parse_action_list(parse_table_entries); } @@ -1404,17 +1409,17 @@ impl Generator { fn get_parse_action_list_id( &self, entry: &ParseTableEntry, - parse_table_entries: &mut Vec<(usize, ParseTableEntry)>, + parse_table_entries: &mut HashMap, next_parse_action_list_index: &mut usize, ) -> usize { - if let Some((index, _)) = parse_table_entries.iter().find(|(_, e)| *e == *entry) { - return *index; + if let Some(&index) = parse_table_entries.get(entry) { + index + } else { + let result = *next_parse_action_list_index; + parse_table_entries.insert(entry.clone(), result); + *next_parse_action_list_index += 1 + entry.actions.len(); + result } - - let result = *next_parse_action_list_index; - parse_table_entries.push((result, entry.clone())); - *next_parse_action_list_index += 1 + entry.actions.len(); - result } fn get_field_map_id( diff --git a/cli/src/generate/tables.rs b/cli/src/generate/tables.rs index 799fe02d..16bf1851 100644 --- a/cli/src/generate/tables.rs +++ b/cli/src/generate/tables.rs @@ -10,7 +10,7 @@ use std::hash::BuildHasherDefault; use indexmap::IndexMap; use rustc_hash::FxHasher; -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) enum ParseAction { Accept, Shift { @@ -33,7 +33,7 @@ pub(crate) enum GotoAction { ShiftExtra, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub(crate) struct ParseTableEntry { pub actions: Vec, pub reusable: bool,