2014-01-19 01:49:56 -08:00
|
|
|
#include "follow_sets.h"
|
2014-01-21 23:38:23 -08:00
|
|
|
#include "first_set.h"
|
2014-01-19 01:49:56 -08:00
|
|
|
#include "rule_transitions.h"
|
|
|
|
|
#include "grammar.h"
|
|
|
|
|
|
|
|
|
|
using std::unordered_map;
|
|
|
|
|
using std::set;
|
|
|
|
|
using std::dynamic_pointer_cast;
|
|
|
|
|
using tree_sitter::rules::Symbol;
|
|
|
|
|
|
|
|
|
|
namespace tree_sitter {
|
|
|
|
|
class Grammar;
|
|
|
|
|
|
|
|
|
|
namespace build_tables {
|
|
|
|
|
unordered_map<Symbol, set<Symbol>> follow_sets(const ParseItem &item, const Grammar &grammar) {
|
|
|
|
|
unordered_map<Symbol, set<Symbol>> result;
|
2014-01-21 23:38:23 -08:00
|
|
|
|
2014-02-09 14:31:27 -08:00
|
|
|
for (auto pair : sym_transitions(item.rule)) {
|
|
|
|
|
auto symbol = *pair.first;
|
|
|
|
|
if (grammar.has_definition(symbol)) {
|
2014-01-21 23:38:23 -08:00
|
|
|
auto following_non_terminals = first_set(pair.second, grammar);
|
|
|
|
|
if (rule_can_be_blank(pair.second)) {
|
2014-01-27 12:40:06 -08:00
|
|
|
following_non_terminals.insert(item.lookahead_sym);
|
2014-01-21 23:38:23 -08:00
|
|
|
}
|
2014-02-09 14:31:27 -08:00
|
|
|
result.insert({ symbol, following_non_terminals });
|
2014-01-19 01:49:56 -08:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-21 23:38:23 -08:00
|
|
|
|
2014-01-19 01:49:56 -08:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|