Fix non-deterministic order in conflict description

This commit is contained in:
Max Brunsfeld 2015-03-07 10:47:37 -08:00
parent 2d436cf141
commit 3458fa6e50
4 changed files with 24 additions and 5 deletions

View file

@ -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 )"));
});
});

View file

@ -4,12 +4,16 @@
#include "compiler/lexical_grammar.h"
#include "compiler/syntax_grammar.h"
#include "compiler/build_tables/parse_item.h"
#include <algorithm>
#include <string>
#include <vector>
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<string> 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) + ": " +

View file

@ -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:

View file

@ -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;