Use hash_combine everywhere
This commit is contained in:
parent
6cfd009503
commit
6935f1d26f
12 changed files with 132 additions and 73 deletions
|
|
@ -44,7 +44,7 @@ class LexTableBuilder {
|
|||
const LexicalGrammar lex_grammar;
|
||||
vector<rule_ptr> separator_rules;
|
||||
LexConflictManager conflict_manager;
|
||||
unordered_map<const LexItemSet, LexStateId, LexItemSet::Hash> lex_state_ids;
|
||||
unordered_map<LexItemSet, LexStateId> lex_state_ids;
|
||||
|
||||
public:
|
||||
LexTableBuilder(ParseTable *parse_table, const LexicalGrammar &lex_grammar)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class ParseTableBuilder {
|
|||
const LexicalGrammar lexical_grammar;
|
||||
ParseConflictManager conflict_manager;
|
||||
unordered_map<Symbol, ParseItemSet> recovery_states;
|
||||
unordered_map<ParseItemSet, ParseStateId, ParseItemSet::Hash> parse_state_ids;
|
||||
unordered_map<ParseItemSet, ParseStateId> parse_state_ids;
|
||||
vector<pair<ParseItemSet, ParseStateId>> item_sets_to_process;
|
||||
ParseTable parse_table;
|
||||
set<string> conflicts;
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
#include "compiler/rules/symbol.h"
|
||||
#include "compiler/rules/repeat.h"
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
||||
using std::hash;
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::unordered_set;
|
||||
|
|
@ -69,20 +69,9 @@ LexItem::CompletionStatus LexItem::completion_status() const {
|
|||
return GetCompletionStatus().apply(rule);
|
||||
}
|
||||
|
||||
size_t LexItem::Hash::operator()(const LexItem &item) const {
|
||||
return hash<Symbol>()(item.lhs) ^ hash<rule_ptr>()(item.rule);
|
||||
}
|
||||
|
||||
size_t LexItemSet::Hash::operator()(const LexItemSet &item_set) const {
|
||||
size_t result = hash<size_t>()(item_set.entries.size());
|
||||
for (const auto &item : item_set.entries)
|
||||
result ^= LexItem::Hash()(item);
|
||||
return result;
|
||||
}
|
||||
|
||||
LexItemSet::LexItemSet() {}
|
||||
|
||||
LexItemSet::LexItemSet(const unordered_set<LexItem, LexItem::Hash> &entries)
|
||||
LexItemSet::LexItemSet(const unordered_set<LexItem> &entries)
|
||||
: entries(entries) {}
|
||||
|
||||
bool LexItemSet::operator==(const LexItemSet &other) const {
|
||||
|
|
@ -103,3 +92,27 @@ bool LexItemSet::Transition::operator==(const LexItemSet::Transition &other) con
|
|||
|
||||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
using tree_sitter::util::hash_combine;
|
||||
using tree_sitter::util::symmetric_hash_combine;
|
||||
using tree_sitter::build_tables::LexItem;
|
||||
using tree_sitter::build_tables::LexItemSet;
|
||||
|
||||
size_t hash<LexItem>::operator()(const LexItem &item) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, item.lhs.index);
|
||||
hash_combine(&result, item.rule);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t hash<LexItemSet>::operator()(const LexItemSet &item_set) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, item_set.entries.size());
|
||||
for (const auto &item : item_set.entries)
|
||||
symmetric_hash_combine(&result, item);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@ class LexItem {
|
|||
bool is_string;
|
||||
};
|
||||
|
||||
struct Hash {
|
||||
size_t operator()(const LexItem &) const;
|
||||
};
|
||||
|
||||
bool operator==(const LexItem &other) const;
|
||||
CompletionStatus completion_status() const;
|
||||
|
||||
|
|
@ -33,23 +29,34 @@ class LexItem {
|
|||
rule_ptr rule;
|
||||
};
|
||||
|
||||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<tree_sitter::build_tables::LexItem> {
|
||||
size_t operator()(const tree_sitter::build_tables::LexItem &) const;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
||||
class LexItemSet {
|
||||
public:
|
||||
LexItemSet();
|
||||
explicit LexItemSet(const std::unordered_set<LexItem, LexItem::Hash> &);
|
||||
explicit LexItemSet(const std::unordered_set<LexItem> &);
|
||||
|
||||
bool operator==(const LexItemSet &) const;
|
||||
|
||||
struct Hash {
|
||||
size_t operator()(const LexItemSet &) const;
|
||||
};
|
||||
|
||||
struct Transition;
|
||||
typedef std::map<rules::CharacterSet, Transition> TransitionMap;
|
||||
|
||||
TransitionMap transitions() const;
|
||||
|
||||
std::unordered_set<LexItem, LexItem::Hash> entries;
|
||||
std::unordered_set<LexItem> entries;
|
||||
};
|
||||
|
||||
struct LexItemSet::Transition {
|
||||
|
|
@ -63,4 +70,13 @@ struct LexItemSet::Transition {
|
|||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct hash<tree_sitter::build_tables::LexItemSet> {
|
||||
size_t operator()(const tree_sitter::build_tables::LexItemSet &) const;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // COMPILER_BUILD_TABLES_LEX_ITEM_H_
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ using std::map;
|
|||
using std::pair;
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::hash;
|
||||
using rules::Symbol;
|
||||
using util::hash_combine;
|
||||
|
||||
|
|
@ -82,13 +81,6 @@ rules::Associativity ParseItem::associativity() const {
|
|||
return production->at(step_index).associativity;
|
||||
}
|
||||
|
||||
size_t ParseItem::Hash::operator()(const ParseItem &item) const {
|
||||
size_t result = hash<int>()(item.variable_index);
|
||||
result ^= hash<unsigned int>()(item.step_index);
|
||||
result ^= hash<const void *>()(static_cast<const void *>(item.production));
|
||||
return result;
|
||||
}
|
||||
|
||||
ParseItemSet::ParseItemSet() {}
|
||||
|
||||
ParseItemSet::ParseItemSet(const map<ParseItem, LookaheadSet> &entries)
|
||||
|
|
@ -98,20 +90,6 @@ bool ParseItemSet::operator==(const ParseItemSet &other) const {
|
|||
return entries == other.entries;
|
||||
}
|
||||
|
||||
size_t ParseItemSet::Hash::operator()(const ParseItemSet &item_set) const {
|
||||
size_t result = hash<size_t>()(item_set.entries.size());
|
||||
for (auto &pair : item_set.entries) {
|
||||
const ParseItem &item = pair.first;
|
||||
result ^= ParseItem::Hash()(item);
|
||||
|
||||
const LookaheadSet &lookahead_set = pair.second;
|
||||
result ^= hash<size_t>()(lookahead_set.entries->size());
|
||||
for (Symbol::Index index : *pair.second.entries)
|
||||
result ^= hash<Symbol::Index>()(index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t ParseItemSet::unfinished_item_signature() const {
|
||||
size_t result = 0;
|
||||
ParseItem previous_item;
|
||||
|
|
@ -156,3 +134,37 @@ void ParseItemSet::add(const ParseItemSet &other) {
|
|||
|
||||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
using tree_sitter::build_tables::ParseItem;
|
||||
using tree_sitter::build_tables::ParseItemSet;
|
||||
using tree_sitter::util::hash_combine;
|
||||
|
||||
template <>
|
||||
struct hash<ParseItem> {
|
||||
size_t operator()(const ParseItem &item) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, item.variable_index);
|
||||
hash_combine(&result, item.step_index);
|
||||
hash_combine(&result, item.production);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
size_t hash<ParseItemSet>::operator()(const ParseItemSet &item_set) const {
|
||||
size_t result = 0;
|
||||
hash_combine(&result, item_set.entries.size());
|
||||
for (auto &pair : item_set.entries) {
|
||||
const ParseItem &item = pair.first;
|
||||
const auto &lookahead_set = pair.second;
|
||||
|
||||
hash_combine(&result, item);
|
||||
hash_combine(&result, lookahead_set.entries->size());
|
||||
for (auto index : *pair.second.entries)
|
||||
hash_combine(&result, index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
|
|
|||
|
|
@ -23,10 +23,6 @@ class ParseItem {
|
|||
rules::Associativity associativity;
|
||||
};
|
||||
|
||||
struct Hash {
|
||||
size_t operator()(const ParseItem &) const;
|
||||
};
|
||||
|
||||
bool operator==(const ParseItem &other) const;
|
||||
bool operator<(const ParseItem &other) const;
|
||||
rules::Symbol lhs() const;
|
||||
|
|
@ -48,10 +44,6 @@ class ParseItemSet {
|
|||
typedef std::map<rules::Symbol, std::pair<ParseItemSet, PrecedenceRange>>
|
||||
TransitionMap;
|
||||
|
||||
struct Hash {
|
||||
size_t operator()(const ParseItemSet &) const;
|
||||
};
|
||||
|
||||
TransitionMap transitions() const;
|
||||
bool operator==(const ParseItemSet &) const;
|
||||
void add(const ParseItemSet &);
|
||||
|
|
@ -63,4 +55,15 @@ class ParseItemSet {
|
|||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
||||
namespace std {
|
||||
|
||||
using tree_sitter::build_tables::ParseItemSet;
|
||||
|
||||
template <>
|
||||
struct hash<tree_sitter::build_tables::ParseItemSet> {
|
||||
size_t operator()(const ParseItemSet &item_set) const;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // COMPILER_BUILD_TABLES_PARSE_ITEM_H_
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
namespace tree_sitter {
|
||||
|
||||
using std::hash;
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
using std::to_string;
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::string;
|
||||
using std::hash;
|
||||
using std::set;
|
||||
using std::vector;
|
||||
using util::hash_combine;
|
||||
|
||||
static void add_range(set<uint32_t> *characters, uint32_t min, uint32_t max) {
|
||||
for (uint32_t c = min; c <= max; c++)
|
||||
|
|
@ -83,14 +84,14 @@ bool CharacterSet::operator<(const CharacterSet &other) const {
|
|||
}
|
||||
|
||||
size_t CharacterSet::hash_code() const {
|
||||
size_t result = hash<bool>()(includes_all);
|
||||
result ^= hash<size_t>()(included_chars.size());
|
||||
for (auto &c : included_chars)
|
||||
result ^= hash<uint32_t>()(c);
|
||||
result <<= 1;
|
||||
result ^= hash<size_t>()(excluded_chars.size());
|
||||
for (auto &c : excluded_chars)
|
||||
result ^= hash<uint32_t>()(c);
|
||||
size_t result = 0;
|
||||
hash_combine(&result, includes_all);
|
||||
hash_combine(&result, included_chars.size());
|
||||
for (uint32_t c : included_chars)
|
||||
hash_combine(&result, c);
|
||||
hash_combine(&result, excluded_chars.size());
|
||||
for (uint32_t c : excluded_chars)
|
||||
hash_combine(&result, c);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <string>
|
||||
#include <set>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
|
@ -10,6 +11,7 @@ using std::string;
|
|||
using std::make_shared;
|
||||
using std::vector;
|
||||
using std::set;
|
||||
using util::symmetric_hash_combine;
|
||||
|
||||
Choice::Choice(const vector<rule_ptr> &elements) : elements(elements) {}
|
||||
|
||||
|
|
@ -50,9 +52,10 @@ bool Choice::operator==(const Rule &rule) const {
|
|||
}
|
||||
|
||||
size_t Choice::hash_code() const {
|
||||
size_t result = std::hash<size_t>()(elements.size());
|
||||
size_t result = 0;
|
||||
symmetric_hash_combine(&result, elements.size());
|
||||
for (const auto &element : elements)
|
||||
result ^= element->hash_code();
|
||||
symmetric_hash_combine(&result, element);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,15 @@
|
|||
#include <map>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/rules/blank.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::hash;
|
||||
using std::make_shared;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using util::hash_combine;
|
||||
|
||||
Metadata::Metadata(rule_ptr rule, map<MetadataKey, int> values)
|
||||
: rule(rule), value(values) {}
|
||||
|
|
@ -25,10 +26,11 @@ bool Metadata::operator==(const Rule &rule) const {
|
|||
}
|
||||
|
||||
size_t Metadata::hash_code() const {
|
||||
size_t result = hash<size_t>()(value.size());
|
||||
size_t result = 0;
|
||||
hash_combine(&result, value.size());
|
||||
for (auto &pair : value) {
|
||||
result ^= hash<int>()(pair.first);
|
||||
result ^= hash<int>()(pair.second);
|
||||
hash_combine<int>(&result, pair.first);
|
||||
hash_combine(&result, pair.second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include "compiler/rules/visitor.h"
|
||||
#include "compiler/util/hash_combine.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace rules {
|
||||
|
||||
using std::string;
|
||||
using std::to_string;
|
||||
using std::hash;
|
||||
using util::hash_combine;
|
||||
|
||||
Symbol::Symbol(Symbol::Index index) : index(index), is_token(false) {}
|
||||
|
||||
|
|
@ -24,7 +25,10 @@ bool Symbol::operator==(const Rule &rule) const {
|
|||
}
|
||||
|
||||
size_t Symbol::hash_code() const {
|
||||
return hash<Symbol::Index>()(index) ^ hash<bool>()(is_token);
|
||||
size_t result = 0;
|
||||
hash_combine(&result, index);
|
||||
hash_combine(&result, is_token);
|
||||
return result;
|
||||
}
|
||||
|
||||
rule_ptr Symbol::copy() const {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@ inline void hash_combine(std::size_t *seed, const T &new_value) {
|
|||
*seed ^= hasher(new_value) + 0x9e3779b9 + (*seed << 6) + (*seed >> 2);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void symmetric_hash_combine(std::size_t *seed, const T &new_value) {
|
||||
std::hash<T> hasher;
|
||||
*seed ^= hasher(new_value);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace tree_sitter
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue