Fix bug in lexical state de-duping

This commit is contained in:
Max Brunsfeld 2015-12-30 11:15:36 -08:00
parent 4b04afac5e
commit e59f6294cb
3 changed files with 6846 additions and 6706 deletions

View file

@ -8,6 +8,7 @@ namespace tree_sitter_examples {
extern const Grammar c = Grammar({
{ "translation_unit", repeat(choice({
sym("preproc_define"),
sym("preproc_call"),
sym("function_definition"),
sym("declaration") })) },
@ -17,10 +18,16 @@ extern const Grammar c = Grammar({
optional(sym("preproc_arg")),
str("\n") }) },
{ "preproc_call", seq({
sym("preproc_directive"),
sym("preproc_arg") }) },
{ "preproc_arg", token(prec(-1, repeat1(choice({
str("\\\n"),
pattern(".") })))) },
{ "preproc_directive", pattern("#\a\\w*") },
{ "function_definition", seq({
optional(sym("declaration_specifiers")),
sym("_type_specifier"),

13503
spec/fixtures/parsers/c.c vendored

File diff suppressed because it is too large Load diff

View file

@ -23,24 +23,34 @@ std::map<size_t, size_t> remove_duplicate_states(std::vector<StateType> *states)
if (duplicates.empty())
break;
std::map<size_t, size_t> new_replacements;
for (size_t i = 0, size = states->size(); i < size; i++) {
size_t new_state_index = i;
auto duplicate = duplicates.find(i);
if (duplicate != duplicates.end())
new_state_index = duplicate->second;
size_t prior_removed = 0;
for (const auto &duplicate : duplicates) {
if (duplicate.first >= new_state_index)
break;
prior_removed++;
}
new_state_index -= prior_removed;
new_replacements.insert({ i, new_state_index });
replacements.insert({ i, new_state_index });
for (auto &replacement : replacements)
if (replacement.second == i)
replacement.second = new_state_index;
}
for (StateType &state : *states)
state.each_action([&duplicates, &replacements](ActionType *action) {
state.each_action([&duplicates, &new_replacements](ActionType *action) {
if (action->type == advance_action) {
size_t state_index = action->state_index;
auto replacement = duplicates.find(action->state_index);
if (replacement != duplicates.end())
state_index = replacement->second;
size_t prior_removed = 0;
for (const auto &replacement : duplicates) {
if (replacement.first >= state_index)
break;
prior_removed++;
}
state_index -= prior_removed;
replacements.insert({ action->state_index, state_index });
action->state_index = state_index;
auto new_replacement = new_replacements.find(action->state_index);
if (new_replacement != new_replacements.end())
action->state_index = new_replacement->second;
}
});