Compute fewer item set closures in item set transitions function
This commit is contained in:
parent
52daffb3f3
commit
1ba8701ada
5 changed files with 26 additions and 36 deletions
|
|
@ -43,10 +43,14 @@ describe("item_set_closure", []() {
|
|||
}, {}, set<Symbol>());
|
||||
|
||||
it("adds items at the beginnings of referenced rules", [&]() {
|
||||
ParseItemSet item_set = item_set_closure(
|
||||
ParseItem(Symbol(0), 0, 100, 0),
|
||||
set<Symbol>({ Symbol(10, SymbolOptionToken) }),
|
||||
grammar);
|
||||
ParseItemSet item_set({
|
||||
{
|
||||
ParseItem(Symbol(0), 0, 100, 0),
|
||||
set<Symbol>({ Symbol(10, SymbolOptionToken) }),
|
||||
}
|
||||
});
|
||||
|
||||
item_set_closure(&item_set, grammar);
|
||||
|
||||
AssertThat(item_set, Equals(ParseItemSet({
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,8 +40,11 @@ class ParseTableBuilder {
|
|||
: grammar(grammar), lex_grammar(lex_grammar) {}
|
||||
|
||||
pair<ParseTable, vector<Conflict>> build() {
|
||||
ParseItem start_item(rules::START(), 0, -2, 0);
|
||||
add_parse_state(item_set_closure(start_item, { rules::END_OF_INPUT() }, grammar));
|
||||
ParseItemSet start_item_set({
|
||||
{ ParseItem(rules::START(), 0, -2, 0), { rules::END_OF_INPUT() } }
|
||||
});
|
||||
item_set_closure(&start_item_set, grammar);
|
||||
add_parse_state(start_item_set);
|
||||
|
||||
while (!item_sets_to_process.empty()) {
|
||||
auto pair = item_sets_to_process.back();
|
||||
|
|
|
|||
|
|
@ -17,19 +17,17 @@ using std::pair;
|
|||
using rules::Symbol;
|
||||
using rules::rule_ptr;
|
||||
|
||||
const ParseItemSet item_set_closure(const ParseItem &starting_item,
|
||||
const set<Symbol> &starting_lookahead_symbols,
|
||||
const SyntaxGrammar &grammar) {
|
||||
ParseItemSet result;
|
||||
void item_set_closure(ParseItemSet *item_set, const SyntaxGrammar &grammar) {
|
||||
vector<pair<ParseItem, set<Symbol>>> items_to_process;
|
||||
items_to_process.push_back({ starting_item, starting_lookahead_symbols });
|
||||
items_to_process.insert(items_to_process.end(), item_set->begin(), item_set->end());
|
||||
item_set->clear();
|
||||
|
||||
while (!items_to_process.empty()) {
|
||||
ParseItem item = items_to_process.back().first;
|
||||
set<Symbol> new_lookahead_symbols = items_to_process.back().second;
|
||||
items_to_process.pop_back();
|
||||
|
||||
set<Symbol> &lookahead_symbols = result[item];
|
||||
set<Symbol> &lookahead_symbols = item_set->operator[](item);
|
||||
size_t previous_size = lookahead_symbols.size();
|
||||
lookahead_symbols.insert(new_lookahead_symbols.begin(),
|
||||
new_lookahead_symbols.end());
|
||||
|
|
@ -70,8 +68,6 @@ const ParseItemSet item_set_closure(const ParseItem &starting_item,
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace build_tables
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef COMPILER_BUILD_TABLES_ITEM_SET_CLOSURE_H_
|
||||
#define COMPILER_BUILD_TABLES_ITEM_SET_CLOSURE_H_
|
||||
|
||||
#include <set>
|
||||
#include "compiler/build_tables/parse_item.h"
|
||||
#include "compiler/rules/symbol.h"
|
||||
|
||||
|
|
@ -11,9 +10,7 @@ class SyntaxGrammar;
|
|||
|
||||
namespace build_tables {
|
||||
|
||||
const ParseItemSet item_set_closure(const ParseItem &,
|
||||
const std::set<rules::Symbol> &,
|
||||
const SyntaxGrammar &);
|
||||
void item_set_closure(ParseItemSet *, const SyntaxGrammar &);
|
||||
|
||||
} // namespace build_tables
|
||||
} // namespace tree_sitter
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace build_tables {
|
|||
|
||||
using std::map;
|
||||
using std::set;
|
||||
using std::vector;
|
||||
using rules::CharacterSet;
|
||||
using rules::Symbol;
|
||||
|
||||
|
|
@ -21,31 +22,20 @@ map<Symbol, ParseItemSet> sym_transitions(const ParseItemSet &item_set,
|
|||
for (const auto &pair : item_set) {
|
||||
const ParseItem &item = pair.first;
|
||||
const set<Symbol> &lookahead_symbols = pair.second;
|
||||
const auto &productions = grammar.productions(item.lhs);
|
||||
if (productions.empty())
|
||||
continue;
|
||||
|
||||
const Production &production = grammar.productions(item.lhs)[item.production_index];
|
||||
if (production.size() <= item.consumed_symbol_count)
|
||||
continue;
|
||||
|
||||
const Symbol &symbol = production.symbol_at(item.consumed_symbol_count);
|
||||
ParseItem new_item(
|
||||
item.lhs,
|
||||
item.production_index,
|
||||
production.rule_id_at(item.consumed_symbol_count + 1),
|
||||
item.consumed_symbol_count + 1
|
||||
);
|
||||
int rule_id = production.rule_id_at(item.consumed_symbol_count + 1);
|
||||
ParseItem new_item(item.lhs, item.production_index, rule_id, item.consumed_symbol_count + 1);
|
||||
|
||||
merge_sym_transition<ParseItemSet>(
|
||||
&result,
|
||||
{ symbol, item_set_closure(new_item, { lookahead_symbols }, grammar) },
|
||||
[](ParseItemSet *left, const ParseItemSet *right) {
|
||||
for (auto &pair : *right)
|
||||
left->operator[](pair.first)
|
||||
.insert(pair.second.begin(), pair.second.end());
|
||||
});
|
||||
result[symbol][new_item].insert(lookahead_symbols.begin(), lookahead_symbols.end());
|
||||
}
|
||||
|
||||
for (auto &pair : result)
|
||||
item_set_closure(&pair.second, grammar);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue