Make ts_compile_grammar take an optional log file, start logging to it
This commit is contained in:
parent
69d8c6f5e6
commit
6fca8f2f4d
13 changed files with 164 additions and 25 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "compiler/log.h"
|
||||
#include "compiler/parse_table.h"
|
||||
#include "compiler/build_tables/parse_item.h"
|
||||
#include "compiler/build_tables/parse_item_set_builder.h"
|
||||
|
|
@ -152,8 +153,8 @@ class ParseTableBuilderImpl : public ParseTableBuilder {
|
|||
|
||||
parse_table.states[state_id].terminal_entries.clear();
|
||||
|
||||
// Add all the tokens that have no conflict with other tokens.
|
||||
LookaheadSet non_conflicting_tokens;
|
||||
// First, identify the conflict-free tokens.
|
||||
LookaheadSet conflict_free_tokens;
|
||||
for (unsigned i = 0; i < lexical_grammar.variables.size(); i++) {
|
||||
Symbol token = Symbol::terminal(i);
|
||||
bool conflicts_with_other_tokens = false;
|
||||
|
|
@ -166,27 +167,41 @@ class ParseTableBuilderImpl : public ParseTableBuilder {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!conflicts_with_other_tokens) non_conflicting_tokens.insert(token);
|
||||
if (!conflicts_with_other_tokens) conflict_free_tokens.insert(token);
|
||||
}
|
||||
|
||||
// Include in the error recover state all of the tokens that are either
|
||||
// conflict-free themselves, or have no conflicts with any conflict-free
|
||||
// tokens.
|
||||
LOG_START("finding non-conflicting tokens for error recovery");
|
||||
LookaheadSet tokens;
|
||||
for (unsigned i = 0; i < lexical_grammar.variables.size(); i++) {
|
||||
Symbol token = Symbol::terminal(i);
|
||||
bool conflicts_with_other_tokens = false;
|
||||
if (!non_conflicting_tokens.contains(token)) {
|
||||
non_conflicting_tokens.for_each([&](Symbol other_token) {
|
||||
if (conflict_free_tokens.contains(token)) {
|
||||
LOG("include %s", symbol_name(token).c_str());
|
||||
parse_table.add_terminal_action(state_id, token, ParseAction::Recover());
|
||||
} else {
|
||||
bool conflicts_with_other_tokens = false;
|
||||
conflict_free_tokens.for_each([&](Symbol other_token) {
|
||||
if (!coincident_tokens_by_token[token.index].contains(other_token) &&
|
||||
(lex_table_builder->get_conflict_status(other_token, token) & CannotMerge)) {
|
||||
LOG(
|
||||
"exclude %s: conflicts with %s",
|
||||
symbol_name(token).c_str(),
|
||||
symbol_name(other_token).c_str()
|
||||
);
|
||||
conflicts_with_other_tokens = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
if (!conflicts_with_other_tokens) {
|
||||
parse_table.add_terminal_action(state_id, token, ParseAction::Recover());
|
||||
if (!conflicts_with_other_tokens) {
|
||||
LOG("include %s", symbol_name(token).c_str());
|
||||
parse_table.add_terminal_action(state_id, token, ParseAction::Recover());
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_END();
|
||||
|
||||
for (size_t i = 0; i < grammar.external_tokens.size(); i++) {
|
||||
if (grammar.external_tokens[i].corresponding_internal_token == rules::NONE()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue