From 3458fa6e5033cb6b477f8028b2da521e27ea4c1c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sat, 7 Mar 2015 10:47:37 -0800 Subject: [PATCH] Fix non-deterministic order in conflict description --- spec/compiler/build_tables/build_conflict_spec.cc | 4 ++-- src/compiler/build_tables/build_conflict.cc | 12 ++++++++++-- src/compiler/parse_table.cc | 10 ++++++++++ src/compiler/parse_table.h | 3 ++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/spec/compiler/build_tables/build_conflict_spec.cc b/spec/compiler/build_tables/build_conflict_spec.cc index a0ab711f..acaecc2d 100644 --- a/spec/compiler/build_tables/build_conflict_spec.cc +++ b/spec/compiler/build_tables/build_conflict_spec.cc @@ -48,7 +48,7 @@ describe("build_conflict", []() { AssertThat(conflict.description, Equals( "lookahead_token: " - "shift ( in_progress_rule2 in_progress_rule1 ) / " + "shift ( in_progress_rule1 in_progress_rule2 ) / " "reduce ( reduced_rule )")); }); @@ -72,7 +72,7 @@ describe("build_conflict", []() { AssertThat(conflict.description, Equals( "lookahead_token: " - "shift ( in_progress_rule2 in_progress_rule1 ) / " + "shift ( in_progress_rule1 in_progress_rule2 ) / " "reduce ( reduced_rule )")); }); }); diff --git a/src/compiler/build_tables/build_conflict.cc b/src/compiler/build_tables/build_conflict.cc index 9c92dc42..0928a62a 100644 --- a/src/compiler/build_tables/build_conflict.cc +++ b/src/compiler/build_tables/build_conflict.cc @@ -4,12 +4,16 @@ #include "compiler/lexical_grammar.h" #include "compiler/syntax_grammar.h" #include "compiler/build_tables/parse_item.h" +#include #include +#include namespace tree_sitter { namespace build_tables { +using std::sort; using std::string; +using std::vector; using rules::Symbol; static string symbol_name(const Symbol &symbol, const SyntaxGrammar &grammar, @@ -36,9 +40,13 @@ static string action_description(const ParseAction &action, switch (action.type) { case ParseActionTypeShift: { string result("shift ("); + vector symbol_names; for (const auto &item : item_set) if (!item.first.consumed_symbols.empty()) - result += " " + symbol_name(item.first.lhs, grammar, lex_grammar); + symbol_names.push_back(symbol_name(item.first.lhs, grammar, lex_grammar)); + sort(symbol_names.begin(), symbol_names.end()); + for (string symbol_name : symbol_names) + result += " " + symbol_name; return result + " )"; } case ParseActionTypeReduce: @@ -53,7 +61,7 @@ Conflict build_conflict(const ParseAction &left, const ParseAction &right, const ParseItemSet &item_set, const Symbol &sym, const SyntaxGrammar &grammar, const LexicalGrammar &lex_grammar) { - if (right.type < left.type) + if (right < left) return build_conflict(right, left, item_set, sym, grammar, lex_grammar); return Conflict(symbol_name(sym, grammar, lex_grammar) + ": " + diff --git a/src/compiler/parse_table.cc b/src/compiler/parse_table.cc index b118acdd..1c546f7d 100644 --- a/src/compiler/parse_table.cc +++ b/src/compiler/parse_table.cc @@ -64,6 +64,16 @@ bool ParseAction::operator==(const ParseAction &other) const { return types_eq && symbols_eq && state_indices_eq && consumed_symbol_counts_eq; } +bool ParseAction::operator<(const ParseAction &other) const { + if (type < other.type) return true; + if (other.type < type) return false; + if (symbol < other.symbol) return true; + if (other.symbol < symbol) return false; + if (state_index < other.state_index) return true; + if (other.state_index < state_index) return false; + return consumed_symbol_count < other.consumed_symbol_count; +} + ostream &operator<<(ostream &stream, const ParseAction &action) { switch (action.type) { case ParseActionTypeError: diff --git a/src/compiler/parse_table.h b/src/compiler/parse_table.h index b5fff4e8..b39f18a2 100644 --- a/src/compiler/parse_table.h +++ b/src/compiler/parse_table.h @@ -36,7 +36,8 @@ class ParseAction { int precedence, int production_id); static ParseAction ShiftExtra(); static ParseAction ReduceExtra(rules::Symbol symbol); - bool operator==(const ParseAction &action) const; + bool operator==(const ParseAction &) const; + bool operator<(const ParseAction &) const; ParseActionType type; rules::Symbol symbol;