From b217cd38fb96871d1091d0dc6315b9bafc103f63 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sun, 13 Jul 2014 17:59:23 -0700 Subject: [PATCH] Handle built-in symbols correctly in conflict manager --- .../build_tables/conflict_manager_spec.cc | 15 +++++++++++++ .../build_tables/parse_conflict_manager.cc | 22 +++++++++++++++---- .../build_tables/parse_conflict_manager.h | 6 +++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/spec/compiler/build_tables/conflict_manager_spec.cc b/spec/compiler/build_tables/conflict_manager_spec.cc index 10ca997e..5e5886b2 100644 --- a/spec/compiler/build_tables/conflict_manager_spec.cc +++ b/spec/compiler/build_tables/conflict_manager_spec.cc @@ -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", [&]() { diff --git a/src/compiler/build_tables/parse_conflict_manager.cc b/src/compiler/build_tables/parse_conflict_manager.cc index 5ca802b7..5f0a6a2f 100644 --- a/src/compiler/build_tables/parse_conflict_manager.cc +++ b/src/compiler/build_tables/parse_conflict_manager.cc @@ -4,6 +4,7 @@ #include #include #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))); } diff --git a/src/compiler/build_tables/parse_conflict_manager.h b/src/compiler/build_tables/parse_conflict_manager.h index b4fa9287..3bdbad9b 100644 --- a/src/compiler/build_tables/parse_conflict_manager.h +++ b/src/compiler/build_tables/parse_conflict_manager.h @@ -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 conflicts() const; + + private: + std::string symbol_name(const rules::Symbol &symbol); + void record_conflict(const rules::Symbol &symbol, const ParseAction &left, const ParseAction &right); }; } }