Make sure conflicts returned by compile are unique
This commit is contained in:
parent
53285f7d0c
commit
e1e0cc6278
7 changed files with 23 additions and 11 deletions
|
|
@ -35,6 +35,7 @@ namespace tree_sitter {
|
|||
Conflict(std::string description);
|
||||
std::string description;
|
||||
bool operator==(const Conflict &other) const;
|
||||
bool operator<(const Conflict &other) const;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream &stream, const Grammar &grammar);
|
||||
|
|
|
|||
|
|
@ -71,8 +71,9 @@ describe("resolving parse conflicts", []() {
|
|||
manager->resolve_parse_action(sym1, ParseAction::Reduce(sym2, 1), ParseAction::Shift(2));
|
||||
manager->resolve_parse_action(sym1, ParseAction::Shift(2), ParseAction::Reduce(sym2, 1));
|
||||
|
||||
AssertThat(manager->conflicts()[0], Equals(Conflict("rule1: shift / reduce rule2")));
|
||||
AssertThat(manager->conflicts()[1], Equals(Conflict("rule1: shift / reduce rule2")));
|
||||
AssertThat(manager->conflicts(), Equals(vector<Conflict>({
|
||||
Conflict("rule1: shift / reduce rule2")
|
||||
})));
|
||||
});
|
||||
|
||||
it("favors the shift", [&]() {
|
||||
|
|
@ -89,8 +90,10 @@ describe("resolving parse conflicts", []() {
|
|||
manager->resolve_parse_action(sym1, ParseAction::Reduce(sym2, 1), ParseAction::Reduce(sym1, 1));
|
||||
manager->resolve_parse_action(sym1, ParseAction::Reduce(sym1, 1), ParseAction::Reduce(sym2, 1));
|
||||
|
||||
AssertThat(manager->conflicts()[0], Equals(Conflict("rule1: reduce rule2 / reduce rule1")));
|
||||
AssertThat(manager->conflicts()[1], Equals(Conflict("rule1: reduce rule1 / reduce rule2")));
|
||||
AssertThat(manager->conflicts(), Equals(vector<Conflict>({
|
||||
Conflict("rule1: reduce rule2 / reduce rule1"),
|
||||
Conflict("rule1: reduce rule1 / reduce rule2")
|
||||
})));
|
||||
});
|
||||
|
||||
it("favors the symbol listed earlier in the grammar", [&]() {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ describe("compiling the example grammars", []() {
|
|||
ofstream file(example_parser_dir + language + ".c");
|
||||
auto result = compile(grammar, language);
|
||||
|
||||
// cout << "\n conflicts for " << language << "\n:" << result.second;
|
||||
// cout << "\n\nconflicts for " << language << ":\n" << result.second;
|
||||
|
||||
file << result.first;
|
||||
file.close();
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ namespace tree_sitter {
|
|||
add_error_lex_state();
|
||||
}
|
||||
|
||||
const vector<Conflict> & conflicts() {
|
||||
const vector<Conflict> conflicts() {
|
||||
return conflict_manager.conflicts();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace tree_sitter {
|
||||
namespace build_tables {
|
||||
|
|
@ -29,7 +30,7 @@ namespace tree_sitter {
|
|||
}
|
||||
|
||||
void ConflictManager::record_conflict(const rules::Symbol &symbol, const ParseAction &left, const ParseAction &right) {
|
||||
conflicts_.push_back(Conflict(rule_names.find(symbol)->second + ": " + message_for_action(left, rule_names) + " / " + message_for_action(right, rule_names)));
|
||||
conflicts_.insert(Conflict(rule_names.find(symbol)->second + ": " + message_for_action(left, rule_names) + " / " + message_for_action(right, rule_names)));
|
||||
}
|
||||
|
||||
ConflictManager::ConflictManager(const PreparedGrammar &parse_grammar,
|
||||
|
|
@ -92,8 +93,10 @@ namespace tree_sitter {
|
|||
return false;
|
||||
}
|
||||
|
||||
const vector<Conflict> & ConflictManager::conflicts() const {
|
||||
return conflicts_;
|
||||
const vector<Conflict> ConflictManager::conflicts() const {
|
||||
vector<Conflict> result;
|
||||
result.insert(result.end(), conflicts_.begin(), conflicts_.end());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "tree_sitter/compiler.h"
|
||||
#include "compiler/parse_table.h"
|
||||
#include "compiler/prepared_grammar.h"
|
||||
|
|
@ -14,7 +15,7 @@ namespace tree_sitter {
|
|||
const PreparedGrammar parse_grammar;
|
||||
const PreparedGrammar lex_grammar;
|
||||
const std::map<rules::Symbol, std::string> rule_names;
|
||||
std::vector<Conflict> conflicts_;
|
||||
std::set<Conflict> conflicts_;
|
||||
|
||||
public:
|
||||
ConflictManager(const PreparedGrammar &parse_grammar,
|
||||
|
|
@ -28,7 +29,7 @@ namespace tree_sitter {
|
|||
const ParseAction &new_action);
|
||||
|
||||
void record_conflict(const rules::Symbol &symbol, const ParseAction &left, const ParseAction &right);
|
||||
const std::vector<Conflict> & conflicts() const;
|
||||
const std::vector<Conflict> conflicts() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ namespace tree_sitter {
|
|||
return other.description == description;
|
||||
}
|
||||
|
||||
bool Conflict::operator<(const tree_sitter::Conflict &other) const {
|
||||
return other.description < description;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream &stream, const Conflict &conflict) {
|
||||
return stream << "#<conflict " + conflict.description + ">";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue