diff --git a/Cargo.lock b/Cargo.lock index a6be4cdc..d71fa1bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -495,6 +495,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "ryu" version = "1.0.5" @@ -689,11 +695,13 @@ dependencies = [ "dirs", "glob", "html-escape", + "indexmap", "lazy_static", "log", "rand", "regex", "regex-syntax", + "rustc-hash", "serde", "serde_derive", "serde_json", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6ec541dd..8d280e5d 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,9 +27,11 @@ difference = "2.0" dirs = "3.0" glob = "0.3.0" html-escape = "0.2.6" +indexmap = "1" lazy_static = "1.2.0" regex = "1" regex-syntax = "0.6.4" +rustc-hash = "1" serde = "1.0" serde_derive = "1.0" smallbitvec = "2.3.0" diff --git a/cli/src/generate/build_tables/build_parse_table.rs b/cli/src/generate/build_tables/build_parse_table.rs index bcce614a..59ee631d 100644 --- a/cli/src/generate/build_tables/build_parse_table.rs +++ b/cli/src/generate/build_tables/build_parse_table.rs @@ -11,10 +11,14 @@ use crate::generate::tables::{ ProductionInfo, ProductionInfoId, }; use anyhow::{anyhow, Result}; +use std::cmp::Ordering; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; use std::fmt::Write; +use std::hash::BuildHasherDefault; use std::u32; -use std::{cmp::Ordering, collections::hash_map::Entry}; + +use indexmap::{map::Entry, IndexMap}; +use rustc_hash::FxHasher; // For conflict reporting, each parse state is associated with an example // sequence of symbols that could lead to that parse state. @@ -49,7 +53,7 @@ struct ParseTableBuilder<'a> { lexical_grammar: &'a LexicalGrammar, variable_info: &'a Vec, core_ids_by_core: HashMap, usize>, - state_ids_by_item_set: HashMap, ParseStateId>, + state_ids_by_item_set: IndexMap, ParseStateId, BuildHasherDefault>, parse_state_info_by_id: Vec>, parse_state_queue: VecDeque, non_terminal_extra_states: Vec<(Symbol, usize)>, @@ -147,13 +151,7 @@ impl<'a> ParseTableBuilder<'a> { Entry::Vacant(v) => { let core = v.key().core(); let core_count = self.core_ids_by_core.len(); - let core_id = match self.core_ids_by_core.entry(core) { - Entry::Occupied(e) => *e.get(), - Entry::Vacant(e) => { - e.insert(core_count); - core_count - } - }; + let core_id = *self.core_ids_by_core.entry(core).or_insert(core_count); let state_id = self.parse_table.states.len(); self.parse_state_info_by_id @@ -163,8 +161,8 @@ impl<'a> ParseTableBuilder<'a> { id: state_id, lex_state_id: 0, external_lex_state_id: 0, - terminal_entries: HashMap::new(), - nonterminal_entries: HashMap::new(), + terminal_entries: IndexMap::default(), + nonterminal_entries: IndexMap::default(), core_id, }); self.parse_state_queue.push_back(ParseStateQueueEntry { @@ -981,7 +979,7 @@ pub(crate) fn build_parse_table<'a>( item_set_builder, variable_info, non_terminal_extra_states: Vec::new(), - state_ids_by_item_set: HashMap::new(), + state_ids_by_item_set: IndexMap::default(), core_ids_by_core: HashMap::new(), parse_state_info_by_id: Vec::new(), parse_state_queue: VecDeque::new(), diff --git a/cli/src/generate/tables.rs b/cli/src/generate/tables.rs index ccbf8895..799fe02d 100644 --- a/cli/src/generate/tables.rs +++ b/cli/src/generate/tables.rs @@ -1,10 +1,15 @@ use super::nfa::CharacterSet; use super::rules::{Alias, Symbol, TokenSet}; -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; pub(crate) type ProductionInfoId = usize; pub(crate) type ParseStateId = usize; pub(crate) type LexStateId = usize; +use std::hash::BuildHasherDefault; + +use indexmap::IndexMap; +use rustc_hash::FxHasher; + #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub(crate) enum ParseAction { Accept, @@ -37,8 +42,8 @@ pub(crate) struct ParseTableEntry { #[derive(Clone, Debug, Default, PartialEq, Eq)] pub(crate) struct ParseState { pub id: ParseStateId, - pub terminal_entries: HashMap, - pub nonterminal_entries: HashMap, + pub terminal_entries: IndexMap>, + pub nonterminal_entries: IndexMap>, pub lex_state_id: usize, pub external_lex_state_id: usize, pub core_id: usize,