Replace LexConflictManager class with action_takes_precedence function
This commit is contained in:
parent
5dc08ccce9
commit
0d267e41aa
7 changed files with 56 additions and 109 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
Loading…
Add table
Add a link
Reference in a new issue