Handle built-in symbols correctly in conflict manager
This commit is contained in:
parent
44c4bf5f5e
commit
b217cd38fb
3 changed files with 37 additions and 6 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "compiler/compiler_spec_helper.h"
|
||||
#include "compiler/rules/built_in_symbols.h"
|
||||
#include "compiler/build_tables/parse_conflict_manager.h"
|
||||
#include "compiler/build_tables/lex_conflict_manager.h"
|
||||
#include "compiler/prepared_grammar.h"
|
||||
|
|
@ -148,6 +149,20 @@ describe("resolving parse conflicts", []() {
|
|||
AssertThat(manager->resolve_parse_action(sym1, shift, reduce), IsFalse());
|
||||
AssertThat(manager->resolve_parse_action(sym1, reduce, shift), IsTrue());
|
||||
});
|
||||
|
||||
describe("when the symbols is a built-in symbol", [&]() {
|
||||
it("records a conflict", [&]() {
|
||||
manager->resolve_parse_action(rules::ERROR(), reduce, shift);
|
||||
AssertThat(manager->conflicts()[0], Equals(
|
||||
Conflict("rule1: shift (precedence 0) / reduce ERROR (precedence 0)")
|
||||
));
|
||||
|
||||
manager->resolve_parse_action(rules::END_OF_INPUT(), reduce, shift);
|
||||
AssertThat(manager->conflicts()[1], Equals(
|
||||
Conflict("rule1: shift (precedence 0) / reduce EOF (precedence 0)")
|
||||
));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the shift has conflicting precedences compared to the reduce", [&]() {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <set>
|
||||
#include "compiler/util/string_helpers.h"
|
||||
#include "compiler/rules/built_in_symbols.h"
|
||||
#include "compiler/prepared_grammar.h"
|
||||
|
||||
namespace tree_sitter {
|
||||
|
|
@ -106,13 +107,26 @@ namespace tree_sitter {
|
|||
}
|
||||
}
|
||||
|
||||
string ParseConflictManager::symbol_name(const rules::Symbol &symbol) {
|
||||
if (symbol.is_built_in()) {
|
||||
if (symbol == rules::ERROR())
|
||||
return "ERROR";
|
||||
else if (symbol == rules::END_OF_INPUT())
|
||||
return "END_OF_INPUT";
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
if (symbol.is_token())
|
||||
return lex_grammar.rule_name(symbol);
|
||||
else
|
||||
return parse_grammar.rule_name(symbol);
|
||||
}
|
||||
|
||||
void ParseConflictManager::record_conflict(const rules::Symbol &symbol,
|
||||
const ParseAction &left,
|
||||
const ParseAction &right) {
|
||||
string name = symbol.is_token() ?
|
||||
lex_grammar.rule_name(symbol) :
|
||||
parse_grammar.rule_name(symbol);
|
||||
conflicts_.insert(Conflict(name + ": " +
|
||||
conflicts_.insert(Conflict(symbol_name(symbol) + ": " +
|
||||
message_for_action(left, parse_grammar) + " / " +
|
||||
message_for_action(right, parse_grammar)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,11 @@ namespace tree_sitter {
|
|||
bool resolve_parse_action(const rules::Symbol &symbol,
|
||||
const ParseAction &old_action,
|
||||
const ParseAction &new_action);
|
||||
|
||||
void record_conflict(const rules::Symbol &symbol, const ParseAction &left, const ParseAction &right);
|
||||
const std::vector<Conflict> conflicts() const;
|
||||
|
||||
private:
|
||||
std::string symbol_name(const rules::Symbol &symbol);
|
||||
void record_conflict(const rules::Symbol &symbol, const ParseAction &left, const ParseAction &right);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue