From 00d953f50750d84aa4e471a078e2966d9000187a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Sat, 13 Feb 2016 14:02:22 -0800 Subject: [PATCH] Generate C code for out-of-context states --- .../build_tables/build_parse_table.cc | 23 +++++++++++-------- src/compiler/generate_code/c_code.cc | 16 +++++++++++++ src/compiler/parse_table.h | 1 + 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/compiler/build_tables/build_parse_table.cc b/src/compiler/build_tables/build_parse_table.cc index 354ee8f6..2592e5e3 100644 --- a/src/compiler/build_tables/build_parse_table.cc +++ b/src/compiler/build_tables/build_parse_table.cc @@ -107,25 +107,23 @@ class ParseTableBuilder { } void add_out_of_context_parse_states() { - map> symbols_by_first_symbol = - build_tables::symbols_by_first_symbol(grammar); - for (size_t token_index = 0; token_index < lexical_grammar.variables.size(); - token_index++) { + map> symbols_by_token = symbols_by_first_symbol(grammar); + for (size_t i = 0; i < lexical_grammar.variables.size(); i++) { + Symbol token(i, true); ParseItemSet item_set; - const set &symbols = - symbols_by_first_symbol[Symbol(token_index, true)]; + const set &symbols = symbols_by_token[token]; for (const auto &parse_state_entry : parse_state_ids) { for (const auto &pair : parse_state_entry.first.entries) { const ParseItem &item = pair.first; const LookaheadSet &lookahead_set = pair.second; - if (symbols.count(item.next_symbol())) item_set.entries[item].insert_all(lookahead_set); } } - add_parse_state(item_set); + ParseStateId state = add_parse_state(item_set); + parse_table.out_of_context_state_indices[token] = state; } } @@ -235,7 +233,14 @@ class ParseTableBuilder { } void remove_duplicate_parse_states() { - remove_duplicate_states(&parse_table.states); + auto replacements = remove_duplicate_states( + &parse_table.states); + + for (auto &pair : parse_table.out_of_context_state_indices) { + auto replacement = replacements.find(pair.second); + if (replacement != replacements.end()) + pair.second = replacement->second; + } } ParseAction *add_action(ParseStateId state_id, Symbol lookahead, diff --git a/src/compiler/generate_code/c_code.cc b/src/compiler/generate_code/c_code.cc index 3eb8ca5e..1e09a977 100644 --- a/src/compiler/generate_code/c_code.cc +++ b/src/compiler/generate_code/c_code.cc @@ -98,6 +98,7 @@ class CCodeGenerator { add_symbol_node_types_list(); add_lex_function(); add_lex_states_list(); + add_out_of_context_parse_states_list(); add_parse_table(); add_parser_export(); @@ -216,6 +217,21 @@ class CCodeGenerator { line(); } + void add_out_of_context_parse_states_list() { + line("static TSStateId ts_out_of_context_states[SYMBOL_COUNT] = {"); + indent([&]() { + for (const auto &entry : parse_table.symbols) { + const rules::Symbol &symbol = entry.first; + ParseStateId state = parse_table.out_of_context_state_indices.find(symbol)->second; + if (symbol.is_token && !symbol.is_built_in()) { + line("[" + symbol_id(symbol) + "] = " + to_string(state) + ","); + } + } + }); + line("};"); + line(); + } + void add_parse_table() { add_parse_actions({ ParseAction::Error() }); diff --git a/src/compiler/parse_table.h b/src/compiler/parse_table.h index c8bf124f..d3dba182 100644 --- a/src/compiler/parse_table.h +++ b/src/compiler/parse_table.h @@ -102,6 +102,7 @@ class ParseTable { std::vector states; std::map symbols; + std::map out_of_context_state_indices; }; } // namespace tree_sitter