Handle aliased parent nodes in query analysis
This commit is contained in:
parent
456b1f6771
commit
2eb04094f8
5 changed files with 225 additions and 112 deletions
|
|
@ -13,6 +13,7 @@ extern "C" {
|
|||
#define TREE_SITTER_LANGUAGE_VERSION_WITH_SYMBOL_DEDUPING 11
|
||||
#define TREE_SITTER_LANGUAGE_VERSION_WITH_SMALL_STATES 11
|
||||
#define TREE_SITTER_LANGUAGE_VERSION_WITH_STATE_COUNT 12
|
||||
#define TREE_SITTER_LANGUAGE_VERSION_WITH_ALIAS_MAP 12
|
||||
|
||||
typedef struct {
|
||||
const TSParseAction *actions;
|
||||
|
|
@ -258,6 +259,32 @@ static inline void ts_language_field_map(
|
|||
*end = &self->field_map_entries[slice.index] + slice.length;
|
||||
}
|
||||
|
||||
static inline void ts_language_aliases_for_symbol(
|
||||
const TSLanguage *self,
|
||||
TSSymbol original_symbol,
|
||||
const TSSymbol **start,
|
||||
const TSSymbol **end
|
||||
) {
|
||||
*start = &self->public_symbol_map[original_symbol];
|
||||
*end = *start + 1;
|
||||
|
||||
if (self->version < TREE_SITTER_LANGUAGE_VERSION_WITH_ALIAS_MAP) return;
|
||||
|
||||
unsigned i = 0;
|
||||
for (;;) {
|
||||
TSSymbol symbol = self->alias_map[i++];
|
||||
if (symbol == 0 || symbol > original_symbol) break;
|
||||
uint16_t count = self->alias_map[i++];
|
||||
if (symbol == original_symbol) {
|
||||
*start = &self->alias_map[i];
|
||||
*end = &self->alias_map[i + count];
|
||||
break;
|
||||
}
|
||||
i += count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -788,24 +788,32 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
for (unsigned i = 0; i < lookahead_iterator.action_count; i++) {
|
||||
const TSParseAction *action = &lookahead_iterator.actions[i];
|
||||
if (action->type == TSParseActionTypeReduce) {
|
||||
TSSymbol symbol = self->language->public_symbol_map[action->params.reduce.symbol];
|
||||
array_search_sorted_by(
|
||||
&subgraphs,
|
||||
0,
|
||||
.symbol,
|
||||
symbol,
|
||||
&subgraph_index,
|
||||
&exists
|
||||
const TSSymbol *aliases, *aliases_end;
|
||||
ts_language_aliases_for_symbol(
|
||||
self->language,
|
||||
action->params.reduce.symbol,
|
||||
&aliases,
|
||||
&aliases_end
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
if (subgraph->nodes.size == 0 || array_back(&subgraph->nodes)->state != state) {
|
||||
array_push(&subgraph->nodes, ((AnalysisSubgraphNode) {
|
||||
.state = state,
|
||||
.production_id = action->params.reduce.production_id,
|
||||
.child_index = action->params.reduce.child_count,
|
||||
.done = true,
|
||||
}));
|
||||
for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {
|
||||
array_search_sorted_by(
|
||||
&subgraphs,
|
||||
0,
|
||||
.symbol,
|
||||
*symbol,
|
||||
&subgraph_index,
|
||||
&exists
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
if (subgraph->nodes.size == 0 || array_back(&subgraph->nodes)->state != state) {
|
||||
array_push(&subgraph->nodes, ((AnalysisSubgraphNode) {
|
||||
.state = state,
|
||||
.production_id = action->params.reduce.production_id,
|
||||
.child_index = action->params.reduce.child_count,
|
||||
.done = true,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (action->type == TSParseActionTypeShift && !action->params.shift.extra) {
|
||||
|
|
@ -815,22 +823,30 @@ static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {
|
|||
}
|
||||
} else if (lookahead_iterator.next_state != 0 && lookahead_iterator.next_state != state) {
|
||||
state_predecessor_map_add(&predecessor_map, lookahead_iterator.next_state, state);
|
||||
TSSymbol symbol = self->language->public_symbol_map[lookahead_iterator.symbol];
|
||||
array_search_sorted_by(
|
||||
&subgraphs,
|
||||
0,
|
||||
.symbol,
|
||||
symbol,
|
||||
&subgraph_index,
|
||||
&exists
|
||||
const TSSymbol *aliases, *aliases_end;
|
||||
ts_language_aliases_for_symbol(
|
||||
self->language,
|
||||
lookahead_iterator.symbol,
|
||||
&aliases,
|
||||
&aliases_end
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
if (
|
||||
subgraph->start_states.size == 0 ||
|
||||
*array_back(&subgraph->start_states) != state
|
||||
)
|
||||
array_push(&subgraph->start_states, state);
|
||||
for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {
|
||||
array_search_sorted_by(
|
||||
&subgraphs,
|
||||
0,
|
||||
.symbol,
|
||||
*symbol,
|
||||
&subgraph_index,
|
||||
&exists
|
||||
);
|
||||
if (exists) {
|
||||
AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];
|
||||
if (
|
||||
subgraph->start_states.size == 0 ||
|
||||
*array_back(&subgraph->start_states) != state
|
||||
)
|
||||
array_push(&subgraph->start_states, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue