Replace LexConflictManager class with action_takes_precedence function

This commit is contained in:
Max Brunsfeld 2014-11-05 23:34:23 -08:00
parent 5dc08ccce9
commit 0d267e41aa
7 changed files with 56 additions and 109 deletions

View file

@ -68,5 +68,42 @@ pair<bool, bool> action_takes_precedence(const ParseAction &new_action,
return { has_precedence, has_conflict };
}
bool action_takes_precedence(const LexAction &new_action,
const LexAction &old_action) {
if (new_action.type < old_action.type)
return !action_takes_precedence(old_action, new_action);
switch (old_action.type) {
case LexActionTypeError:
return true;
case LexActionTypeAccept: {
int old_precedence = *old_action.precedence_values.begin();
switch (new_action.type) {
case LexActionTypeAccept: {
int new_precedence = *new_action.precedence_values.begin();
if (new_precedence > old_precedence)
return true;
else if (new_precedence < old_precedence)
return false;
else
return new_action.symbol.index < old_action.symbol.index;
}
case LexActionTypeAdvance:
return true;
default:
return false;
}
return true;
}
default:
return false;
}
}
} // namespace build_tables
} // namespace tree_sitter

View file

@ -15,6 +15,9 @@ std::pair<bool, bool> action_takes_precedence(const ParseAction &new_action,
const rules::Symbol &symbol,
const SyntaxGrammar &grammar);
bool action_takes_precedence(const LexAction &new_action,
const LexAction &old_action);
} // namespace build_tables
} // namespace tree_sitter

View file

@ -4,8 +4,8 @@
#include <unordered_map>
#include <utility>
#include <vector>
#include "compiler/build_tables/action_takes_precedence.h"
#include "compiler/build_tables/item_set_transitions.h"
#include "compiler/build_tables/lex_conflict_manager.h"
#include "compiler/build_tables/lex_item.h"
#include "compiler/parse_table.h"
#include "compiler/prepared_grammar.h"
@ -31,15 +31,12 @@ using rules::Symbol;
class LexTableBuilder {
const LexicalGrammar lex_grammar;
ParseTable *parse_table;
LexConflictManager conflict_manager;
unordered_map<const LexItemSet, LexStateId> lex_state_ids;
LexTable lex_table;
public:
LexTableBuilder(ParseTable *parse_table, const LexicalGrammar &lex_grammar)
: lex_grammar(lex_grammar),
parse_table(parse_table),
conflict_manager(LexConflictManager(lex_grammar)) {}
: lex_grammar(lex_grammar), parse_table(parse_table) {}
LexTable build() {
for (auto &parse_state : parse_table->states) {
@ -98,8 +95,8 @@ class LexTableBuilder {
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));
if (conflict_manager.resolve_lex_action(
lex_table.state(state_id).default_action, action))
if (action_takes_precedence(action,
lex_table.state(state_id).default_action))
lex_table.state(state_id).actions[rule] = action;
}
}
@ -109,7 +106,7 @@ class LexTableBuilder {
if (item.is_done()) {
auto current_action = lex_table.state(state_id).default_action;
auto new_action = LexAction::Accept(item.lhs, item.precedence());
if (conflict_manager.resolve_lex_action(current_action, new_action))
if (action_takes_precedence(new_action, current_action))
lex_table.state(state_id).default_action = new_action;
}
}

View file

@ -1,49 +0,0 @@
#include "compiler/build_tables/lex_conflict_manager.h"
#include "compiler/util/string_helpers.h"
#include "compiler/prepared_grammar.h"
namespace tree_sitter {
namespace build_tables {
LexConflictManager::LexConflictManager(const LexicalGrammar &grammar)
: grammar(grammar) {}
bool LexConflictManager::resolve_lex_action(const LexAction &old_action,
const LexAction &new_action) {
if (new_action.type < old_action.type)
return !resolve_lex_action(new_action, old_action);
switch (old_action.type) {
case LexActionTypeError:
return true;
case LexActionTypeAccept: {
int old_precedence = *old_action.precedence_values.begin();
switch (new_action.type) {
case LexActionTypeAccept: {
int new_precedence = *new_action.precedence_values.begin();
if (new_precedence > old_precedence)
return true;
else if (new_precedence < old_precedence)
return false;
else
return new_action.symbol.index < old_action.symbol.index;
}
case LexActionTypeAdvance:
return true;
default:
return false;
}
return true;
}
default:
return false;
}
}
} // namespace build_tables
} // namespace tree_sitter

View file

@ -1,23 +0,0 @@
#ifndef COMPILER_BUILD_TABLES_LEX_CONFLICT_MANAGER_H_
#define COMPILER_BUILD_TABLES_LEX_CONFLICT_MANAGER_H_
#include "tree_sitter/compiler.h"
#include "compiler/lex_table.h"
#include "compiler/prepared_grammar.h"
namespace tree_sitter {
namespace build_tables {
class LexConflictManager {
const LexicalGrammar grammar;
public:
explicit LexConflictManager(const LexicalGrammar &grammar);
bool resolve_lex_action(const LexAction &old_action,
const LexAction &new_action);
};
} // namespace build_tables
} // namespace tree_sitter
#endif // COMPILER_BUILD_TABLES_LEX_CONFLICT_MANAGER_H_