From 257b8d7b681a5643b14c01a6c399b133a9d9ab80 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 30 Dec 2013 23:52:38 -0800 Subject: [PATCH] Update rule hash implementation --- spec/fixtures/parsers/arithmetic.c | 52 ++++++++++++++---------------- src/compiler/rules/blank.cpp | 4 +++ src/compiler/rules/blank.h | 2 ++ src/compiler/rules/character.cpp | 5 +++ src/compiler/rules/character.h | 2 ++ src/compiler/rules/choice.cpp | 4 +++ src/compiler/rules/choice.h | 2 ++ src/compiler/rules/pattern.cpp | 7 +++- src/compiler/rules/pattern.h | 3 ++ src/compiler/rules/repeat.cpp | 4 +++ src/compiler/rules/repeat.h | 2 ++ src/compiler/rules/rule.h | 3 +- src/compiler/rules/seq.cpp | 4 +++ src/compiler/rules/seq.h | 2 ++ src/compiler/rules/string.cpp | 5 +++ src/compiler/rules/string.h | 2 ++ src/compiler/rules/symbol.cpp | 5 +++ src/compiler/rules/symbol.h | 2 ++ 18 files changed, 80 insertions(+), 30 deletions(-) diff --git a/spec/fixtures/parsers/arithmetic.c b/spec/fixtures/parsers/arithmetic.c index 7316c18e..f77cdd19 100644 --- a/spec/fixtures/parsers/arithmetic.c +++ b/spec/fixtures/parsers/arithmetic.c @@ -63,7 +63,7 @@ static void ts_lex(TSParser *parser) { LEX_ERROR(); case 10: if (isdigit(LOOKAHEAD_CHAR())) - ADVANCE(6); + ADVANCE(8); LEX_ERROR(); case 11: ACCEPT_TOKEN(ts_symbol_left_paren); @@ -81,47 +81,43 @@ static void ts_lex(TSParser *parser) { if (isdigit(LOOKAHEAD_CHAR())) ADVANCE(4); if (isalnum(LOOKAHEAD_CHAR())) - ADVANCE(16); + ADVANCE(1); LEX_ERROR(); case 16: - if (isalnum(LOOKAHEAD_CHAR())) - ADVANCE(2); - LEX_ERROR(); - case 17: ACCEPT_TOKEN(ts_symbol_expression); - case 18: + case 17: if (LOOKAHEAD_CHAR() == '*') - ADVANCE(19); + ADVANCE(18); LEX_ERROR(); - case 19: + case 18: ACCEPT_TOKEN(ts_symbol_times); - case 20: + case 19: if (LOOKAHEAD_CHAR() == '(') ADVANCE(11); if (isdigit(LOOKAHEAD_CHAR())) ADVANCE(4); if (isalnum(LOOKAHEAD_CHAR())) - ADVANCE(16); + ADVANCE(1); LEX_ERROR(); - case 21: + case 20: ACCEPT_TOKEN(ts_symbol_term); - case 22: + case 21: ACCEPT_TOKEN(ts_symbol_factor); - case 23: + case 22: if (LOOKAHEAD_CHAR() == '(') ADVANCE(11); if (isdigit(LOOKAHEAD_CHAR())) ADVANCE(4); if (isalnum(LOOKAHEAD_CHAR())) - ADVANCE(16); + ADVANCE(1); + LEX_ERROR(); + case 23: + if (LOOKAHEAD_CHAR() == ')') + ADVANCE(24); LEX_ERROR(); case 24: - if (LOOKAHEAD_CHAR() == ')') - ADVANCE(25); - LEX_ERROR(); - case 25: ACCEPT_TOKEN(ts_symbol_right_paren); - case 26: + case 25: ACCEPT_TOKEN(ts_symbol_factor); default: LEX_ERROR(); @@ -183,13 +179,13 @@ TSTree ts_parse_arithmetic(const char *input) { PARSE_ERROR(); } case 4: - SET_LEX_STATE(17); + SET_LEX_STATE(16); switch (LOOKAHEAD_SYM()) { default: REDUCE(ts_symbol_expression, 3); } case 5: - SET_LEX_STATE(18); + SET_LEX_STATE(17); switch (LOOKAHEAD_SYM()) { case ts_symbol_times: SHIFT(6); @@ -197,7 +193,7 @@ TSTree ts_parse_arithmetic(const char *input) { PARSE_ERROR(); } case 6: - SET_LEX_STATE(20); + SET_LEX_STATE(19); switch (LOOKAHEAD_SYM()) { case ts_symbol_left_paren: SHIFT(9); @@ -211,19 +207,19 @@ TSTree ts_parse_arithmetic(const char *input) { PARSE_ERROR(); } case 7: - SET_LEX_STATE(21); + SET_LEX_STATE(20); switch (LOOKAHEAD_SYM()) { default: REDUCE(ts_symbol_term, 3); } case 8: - SET_LEX_STATE(22); + SET_LEX_STATE(21); switch (LOOKAHEAD_SYM()) { default: REDUCE(ts_symbol_factor, 1); } case 9: - SET_LEX_STATE(23); + SET_LEX_STATE(22); switch (LOOKAHEAD_SYM()) { case ts_symbol_left_paren: SHIFT(9); @@ -241,7 +237,7 @@ TSTree ts_parse_arithmetic(const char *input) { PARSE_ERROR(); } case 10: - SET_LEX_STATE(24); + SET_LEX_STATE(23); switch (LOOKAHEAD_SYM()) { case ts_symbol_right_paren: SHIFT(11); @@ -249,7 +245,7 @@ TSTree ts_parse_arithmetic(const char *input) { PARSE_ERROR(); } case 11: - SET_LEX_STATE(26); + SET_LEX_STATE(25); switch (LOOKAHEAD_SYM()) { default: REDUCE(ts_symbol_factor, 3); diff --git a/src/compiler/rules/blank.cpp b/src/compiler/rules/blank.cpp index db011510..80207631 100644 --- a/src/compiler/rules/blank.cpp +++ b/src/compiler/rules/blank.cpp @@ -9,6 +9,10 @@ namespace tree_sitter { return dynamic_cast(&rule) != nullptr; } + size_t Blank::hash_code() const { + return typeid(this).hash_code(); + } + std::string Blank::to_string() const { return "#"; } diff --git a/src/compiler/rules/blank.h b/src/compiler/rules/blank.h index 8d9b72eb..f58eb12c 100644 --- a/src/compiler/rules/blank.h +++ b/src/compiler/rules/blank.h @@ -8,8 +8,10 @@ namespace tree_sitter { class Blank : public Rule { public: Blank(); + bool operator==(const Rule& other) const; std::string to_string() const; + size_t hash_code() const; void accept(Visitor &visitor) const; }; } diff --git a/src/compiler/rules/character.cpp b/src/compiler/rules/character.cpp index 0f251775..f8a9bf87 100644 --- a/src/compiler/rules/character.cpp +++ b/src/compiler/rules/character.cpp @@ -2,6 +2,7 @@ #include "transition_map.h" using std::string; +using std::hash; namespace tree_sitter { namespace rules { @@ -14,6 +15,10 @@ namespace tree_sitter { return other && (other->value == value); } + size_t Character::hash_code() const { + return typeid(this).hash_code() ^ hash()(CharMatchToString(value)); + } + string Character::to_string() const { return string("#"; } diff --git a/src/compiler/rules/character.h b/src/compiler/rules/character.h index 23568cbb..f8cd4343 100644 --- a/src/compiler/rules/character.h +++ b/src/compiler/rules/character.h @@ -11,7 +11,9 @@ namespace tree_sitter { Character(char character); Character(CharClass character_class); Character(char min_character, char max_character); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; diff --git a/src/compiler/rules/choice.cpp b/src/compiler/rules/choice.cpp index d9c0ab9c..f631f3a4 100644 --- a/src/compiler/rules/choice.cpp +++ b/src/compiler/rules/choice.cpp @@ -12,6 +12,10 @@ namespace tree_sitter { return other && (*other->left == *left) && (*other->right == *right); } + size_t Choice::hash_code() const { + return typeid(this).hash_code() ^ left->hash_code() ^ right->hash_code(); + } + string Choice::to_string() const { return string("#to_string() + " " + right->to_string() + ">"; } diff --git a/src/compiler/rules/choice.h b/src/compiler/rules/choice.h index 7cf04608..4f28ef14 100644 --- a/src/compiler/rules/choice.h +++ b/src/compiler/rules/choice.h @@ -8,7 +8,9 @@ namespace tree_sitter { class Choice : public Rule { public: Choice(rule_ptr left, rule_ptr right); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; diff --git a/src/compiler/rules/pattern.cpp b/src/compiler/rules/pattern.cpp index 40b9b2e4..1a594799 100644 --- a/src/compiler/rules/pattern.cpp +++ b/src/compiler/rules/pattern.cpp @@ -2,6 +2,7 @@ #include "transition_map.h" using std::string; +using std::hash; namespace tree_sitter { namespace rules { @@ -107,7 +108,11 @@ namespace tree_sitter { auto pattern = dynamic_cast(&other); return pattern && (pattern->value == value); } - + + size_t Pattern::hash_code() const { + return typeid(this).hash_code() ^ hash()(value); + } + string Pattern::to_string() const { return string("#"; } diff --git a/src/compiler/rules/pattern.h b/src/compiler/rules/pattern.h index 4033ecfa..efec73d7 100644 --- a/src/compiler/rules/pattern.h +++ b/src/compiler/rules/pattern.h @@ -9,9 +9,12 @@ namespace tree_sitter { const std::string value; public: Pattern(const std::string &string); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; + rule_ptr to_rule_tree() const; }; } diff --git a/src/compiler/rules/repeat.cpp b/src/compiler/rules/repeat.cpp index 9f8ac75e..9fa62ccf 100644 --- a/src/compiler/rules/repeat.cpp +++ b/src/compiler/rules/repeat.cpp @@ -12,6 +12,10 @@ namespace tree_sitter { return other && (*other->content == *content); } + size_t Repeat::hash_code() const { + return typeid(this).hash_code() ^ content->hash_code(); + } + string Repeat::to_string() const { return string("#to_string() + ">"; } diff --git a/src/compiler/rules/repeat.h b/src/compiler/rules/repeat.h index db1a99f6..5ddb60a0 100644 --- a/src/compiler/rules/repeat.h +++ b/src/compiler/rules/repeat.h @@ -8,7 +8,9 @@ namespace tree_sitter { class Repeat : public Rule { public: Repeat(rule_ptr content); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; diff --git a/src/compiler/rules/rule.h b/src/compiler/rules/rule.h index fea3f331..cb5d9d86 100644 --- a/src/compiler/rules/rule.h +++ b/src/compiler/rules/rule.h @@ -10,6 +10,7 @@ namespace tree_sitter { class Rule { public: virtual bool operator==(const Rule& other) const = 0; + virtual size_t hash_code() const = 0; virtual std::string to_string() const = 0; virtual void accept(Visitor &visitor) const = 0; }; @@ -24,7 +25,7 @@ namespace std { template<> struct hash { size_t operator()(const tree_sitter::rules::Rule &rule) { - return std::hash()(rule.to_string()); + return rule.hash_code(); } }; } diff --git a/src/compiler/rules/seq.cpp b/src/compiler/rules/seq.cpp index 4ac99e85..852177b8 100644 --- a/src/compiler/rules/seq.cpp +++ b/src/compiler/rules/seq.cpp @@ -12,6 +12,10 @@ namespace tree_sitter { return other && (*other->left == *left) && (*other->right == *right); } + size_t Seq::hash_code() const { + return typeid(this).hash_code() ^ left->hash_code() ^ right->hash_code(); + } + string Seq::to_string() const { return string("#to_string() + " " + right->to_string() + ">"; } diff --git a/src/compiler/rules/seq.h b/src/compiler/rules/seq.h index a4a0c340..c7c64131 100644 --- a/src/compiler/rules/seq.h +++ b/src/compiler/rules/seq.h @@ -8,7 +8,9 @@ namespace tree_sitter { class Seq : public Rule { public: Seq(rule_ptr left, rule_ptr right); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; diff --git a/src/compiler/rules/string.cpp b/src/compiler/rules/string.cpp index 55cb709f..37a3f607 100644 --- a/src/compiler/rules/string.cpp +++ b/src/compiler/rules/string.cpp @@ -2,6 +2,7 @@ #include "transition_map.h" using std::string; +using std::hash; namespace tree_sitter { namespace rules { @@ -12,6 +13,10 @@ namespace tree_sitter { return (other != NULL) && (other->value == value); } + size_t String::hash_code() const { + return typeid(this).hash_code() ^ hash()(value); + } + string String::to_string() const { return string("#"; } diff --git a/src/compiler/rules/string.h b/src/compiler/rules/string.h index 09232b09..30ab2cf8 100644 --- a/src/compiler/rules/string.h +++ b/src/compiler/rules/string.h @@ -8,7 +8,9 @@ namespace tree_sitter { class String : public Rule { public: String(std::string value); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const; diff --git a/src/compiler/rules/symbol.cpp b/src/compiler/rules/symbol.cpp index cf326216..fbfad5d4 100644 --- a/src/compiler/rules/symbol.cpp +++ b/src/compiler/rules/symbol.cpp @@ -2,6 +2,7 @@ #include "transition_map.h" using std::string; +using std::hash; namespace tree_sitter { namespace rules { @@ -12,6 +13,10 @@ namespace tree_sitter { return other && (other->name == name); } + size_t Symbol::hash_code() const { + return typeid(this).hash_code() ^ hash()(name); + } + string Symbol::to_string() const { return string("#"; } diff --git a/src/compiler/rules/symbol.h b/src/compiler/rules/symbol.h index dbb0d24a..80f93cd9 100644 --- a/src/compiler/rules/symbol.h +++ b/src/compiler/rules/symbol.h @@ -8,7 +8,9 @@ namespace tree_sitter { class Symbol : public Rule { public: Symbol(const std::string &name); + bool operator==(const Rule& other) const; + size_t hash_code() const; std::string to_string() const; void accept(Visitor &visitor) const;