From 5455fb977f52ca0743f7df019ef7fa377dbbf354 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 5 Oct 2015 18:02:59 -0700 Subject: [PATCH] Use PrecedenceRange in build_lex_table --- .../build_tables/lex_conflict_manager_spec.cc | 8 ++-- src/compiler/build_tables/build_lex_table.cc | 44 +++++++++---------- .../build_tables/lex_conflict_manager.cc | 4 +- src/compiler/lex_table.cc | 14 +++--- src/compiler/lex_table.h | 7 +-- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/spec/compiler/build_tables/lex_conflict_manager_spec.cc b/spec/compiler/build_tables/lex_conflict_manager_spec.cc index 6cfca006..ab3c17b6 100644 --- a/spec/compiler/build_tables/lex_conflict_manager_spec.cc +++ b/spec/compiler/build_tables/lex_conflict_manager_spec.cc @@ -22,19 +22,19 @@ describe("LexConflictManager", []() { Symbol sym3(2, true); it("favors non-errors over lexical errors", [&]() { - update = conflict_manager.resolve(LexAction::Advance(2, {0}), LexAction::Error()); + update = conflict_manager.resolve(LexAction::Advance(2, {0, 0}), LexAction::Error()); AssertThat(update, IsTrue()); - update = conflict_manager.resolve(LexAction::Error(), LexAction::Advance(2, {0})); + update = conflict_manager.resolve(LexAction::Error(), LexAction::Advance(2, {0, 0})); AssertThat(update, IsFalse()); }); describe("accept-token/advance conflicts", [&]() { it("prefers the advance", [&]() { - update = conflict_manager.resolve(LexAction::Advance(1, { 0 }), LexAction::Accept(sym3, 3)); + update = conflict_manager.resolve(LexAction::Advance(1, { 0, 0 }), LexAction::Accept(sym3, 3)); AssertThat(update, IsTrue()); - update = conflict_manager.resolve(LexAction::Accept(sym3, 3), LexAction::Advance(1, { 0 })); + update = conflict_manager.resolve(LexAction::Accept(sym3, 3), LexAction::Advance(1, { 0, 0 })); AssertThat(update, IsFalse()); }); }); diff --git a/src/compiler/build_tables/build_lex_table.cc b/src/compiler/build_tables/build_lex_table.cc index e7b29a0c..b9a98615 100644 --- a/src/compiler/build_tables/build_lex_table.cc +++ b/src/compiler/build_tables/build_lex_table.cc @@ -43,31 +43,32 @@ class LexTableBuilder { conflict_manager(lex_grammar), parse_table(parse_table) { vector separators; - for (const auto &rule : lex_grammar.separators) + for (const rule_ptr &rule : lex_grammar.separators) separators.push_back(rules::Repeat::build(rule)); separator_rule = rules::Choice::build(separators); } LexTable build() { - for (auto &parse_state : parse_table->states) { + for (ParseState &parse_state : parse_table->states) { LexItemSet item_set = build_lex_item_set(parse_state.expected_inputs()); parse_state.lex_state_id = add_lex_state(item_set); } - add_error_lex_state(); + + LexItemSet error_item_set = build_lex_item_set(parse_table->symbols); + populate_lex_state(error_item_set, LexTable::ERROR_STATE_ID); + return lex_table; } private: LexItemSet build_lex_item_set(const set &symbols) { LexItemSet result; - for (const auto &symbol : symbols) { + for (const Symbol &symbol : symbols) { if (symbol == rules::ERROR()) continue; - - if (symbol == rules::END_OF_INPUT()) + else if (symbol == rules::END_OF_INPUT()) result.entries.insert( LexItem(symbol, after_separators(CharacterSet().include(0).copy()))); - else if (symbol.is_token) result.entries.insert(LexItem( symbol, after_separators(lex_grammar.variables[symbol.index].rule))); @@ -80,31 +81,26 @@ class LexTableBuilder { if (pair == lex_state_ids.end()) { LexStateId state_id = lex_table.add_state(); lex_state_ids[item_set] = state_id; - - add_accept_token_actions(item_set, state_id); - add_advance_actions(item_set, state_id); - add_token_start(item_set, state_id); - + populate_lex_state(item_set, state_id); return state_id; } else { return pair->second; } } - void add_error_lex_state() { - LexItemSet item_set = build_lex_item_set(parse_table->symbols); - add_accept_token_actions(item_set, LexTable::ERROR_STATE_ID); - add_advance_actions(item_set, LexTable::ERROR_STATE_ID); - add_token_start(item_set, LexTable::ERROR_STATE_ID); + void populate_lex_state(const LexItemSet &item_set, LexStateId state_id) { + add_accept_token_actions(item_set, state_id); + add_advance_actions(item_set, state_id); + add_token_start(item_set, state_id); } void add_advance_actions(const LexItemSet &item_set, LexStateId state_id) { for (const auto &transition : item_set.transitions()) { - CharacterSet rule = transition.first; - LexItemSet new_item_set = transition.second; + const CharacterSet &rule = transition.first; + const LexItemSet &new_item_set = transition.second; LexStateId new_state_id = add_lex_state(new_item_set); auto action = LexAction::Advance( - new_state_id, precedence_values_for_item_set(new_item_set)); + new_state_id, precedence_range_for_item_set(new_item_set)); if (conflict_manager.resolve(action, lex_table.state(state_id).default_action)) lex_table.state(state_id).actions[rule] = action; @@ -140,12 +136,12 @@ class LexTableBuilder { }); } - set precedence_values_for_item_set(const LexItemSet &item_set) const { - set result; + PrecedenceRange precedence_range_for_item_set(const LexItemSet &item_set) const { + PrecedenceRange result; for (const auto &item : item_set.entries) { auto precedence_range = get_metadata(item.rule, rules::PRECEDENCE); - result.insert(precedence_range.min); - result.insert(precedence_range.max); + result.add(precedence_range.min); + result.add(precedence_range.max); } return result; } diff --git a/src/compiler/build_tables/lex_conflict_manager.cc b/src/compiler/build_tables/lex_conflict_manager.cc index 473edb4e..c272996b 100644 --- a/src/compiler/build_tables/lex_conflict_manager.cc +++ b/src/compiler/build_tables/lex_conflict_manager.cc @@ -19,11 +19,11 @@ bool LexConflictManager::resolve(const LexAction &new_action, return true; case LexActionTypeAccept: { - int old_precedence = *old_action.precedence_values.begin(); + int old_precedence = old_action.precedence_range.min; switch (new_action.type) { case LexActionTypeAccept: { - int new_precedence = *new_action.precedence_values.begin(); + int new_precedence = new_action.precedence_range.min; if (new_precedence > old_precedence) return true; else if (new_precedence < old_precedence) diff --git a/src/compiler/lex_table.cc b/src/compiler/lex_table.cc index 88e07b7f..d50ecef0 100644 --- a/src/compiler/lex_table.cc +++ b/src/compiler/lex_table.cc @@ -14,26 +14,26 @@ LexAction::LexAction() : type(LexActionTypeError), symbol(Symbol(-1)), state_index(-1), - precedence_values({ 0 }) {} + precedence_range({ 0, 0 }) {} LexAction::LexAction(LexActionType type, size_t state_index, Symbol symbol, - set precedence_values) + PrecedenceRange precedence_range) : type(type), symbol(symbol), state_index(state_index), - precedence_values(precedence_values) {} + precedence_range(precedence_range) {} LexAction LexAction::Error() { - return LexAction(LexActionTypeError, -1, Symbol(-1), { 0 }); + return LexAction(LexActionTypeError, -1, Symbol(-1), { 0, 0 }); } -LexAction LexAction::Advance(size_t state_index, set precedence_values) { +LexAction LexAction::Advance(size_t state_index, PrecedenceRange precedence_range) { return LexAction(LexActionTypeAdvance, state_index, Symbol(-1), - precedence_values); + precedence_range); } LexAction LexAction::Accept(Symbol symbol, int precedence) { - return LexAction(LexActionTypeAccept, -1, symbol, { precedence }); + return LexAction(LexActionTypeAccept, -1, symbol, { precedence, precedence }); } bool LexAction::operator==(const LexAction &other) const { diff --git a/src/compiler/lex_table.h b/src/compiler/lex_table.h index 8d433598..ab6c4a3f 100644 --- a/src/compiler/lex_table.h +++ b/src/compiler/lex_table.h @@ -5,6 +5,7 @@ #include #include #include +#include "compiler/precedence_range.h" #include "compiler/rules/symbol.h" #include "compiler/rules/character_set.h" @@ -18,19 +19,19 @@ typedef enum { class LexAction { LexAction(LexActionType type, size_t state_index, rules::Symbol symbol, - std::set precedence_values); + PrecedenceRange precedence_range); public: LexAction(); static LexAction Accept(rules::Symbol symbol, int precedence); static LexAction Error(); - static LexAction Advance(size_t state_index, std::set precedence_values); + static LexAction Advance(size_t state_index, PrecedenceRange precedence_range); bool operator==(const LexAction &action) const; LexActionType type; rules::Symbol symbol; size_t state_index; - std::set precedence_values; + PrecedenceRange precedence_range; }; } // namespace tree_sitter