diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index 6e8f3040..81f9a92e 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -60,7 +60,6 @@ typedef struct TSLexer { } TSLexer; typedef enum { - TSParseActionTypeError, TSParseActionTypeShift, TSParseActionTypeReduce, TSParseActionTypeAccept, @@ -75,7 +74,7 @@ typedef struct { unsigned short child_count; }; }; - TSParseActionType type : 3; + TSParseActionType type : 4; bool extra : 1; bool fragile : 1; } TSParseAction; @@ -146,11 +145,6 @@ struct TSLanguage { * Parse Table Macros */ -#define ERROR() \ - { \ - { .type = TSParseActionTypeError } \ - } - #define SHIFT(to_state_value) \ { \ { .type = TSParseActionTypeShift, .to_state = to_state_value } \ diff --git a/src/compiler/generate_code/c_code.cc b/src/compiler/generate_code/c_code.cc index 92d7a57f..101947ca 100644 --- a/src/compiler/generate_code/c_code.cc +++ b/src/compiler/generate_code/c_code.cc @@ -214,16 +214,18 @@ class CCodeGenerator { void add_recovery_parse_states_list() { line("static TSParseAction ts_recovery_actions[SYMBOL_COUNT] = {"); indent([&]() { - for (const auto &entry : parse_table.error_state.entries) { - if (!entry.second.actions.empty()) { - line("[" + symbol_id(entry.first) + "] = "); - ParseAction action = entry.second.actions[0]; - if (action.extra) { - add("RECOVER_EXTRA(),"); - } else { + for (const auto &pair : parse_table.symbols) { + const rules::Symbol &symbol = pair.first; + line("[" + symbol_id(pair.first) + "] = "); + const auto &entry = parse_table.error_state.entries.find(symbol); + if (entry != parse_table.error_state.entries.end()) { + ParseAction action = entry->second.actions[0]; + if (!action.extra) { add("RECOVER(" + to_string(action.state_index) + "),"); + continue; } } + add("RECOVER_EXTRA(),"); } }); line("};"); @@ -231,8 +233,7 @@ class CCodeGenerator { } void add_parse_table() { - add_parse_action_list_id( - ParseTableEntry{ { ParseAction::Error() }, true, false }); + add_parse_action_list_id(ParseTableEntry{ {}, true, false }); size_t state_id = 0; line("#pragma GCC diagnostic push"); @@ -349,7 +350,6 @@ class CCodeGenerator { add(" "); switch (action.type) { case ParseActionTypeError: - add("ERROR()"); break; case ParseActionTypeAccept: add("ACCEPT_INPUT()"); diff --git a/src/runtime/language.c b/src/runtime/language.c index 3015a058..b1360f8c 100644 --- a/src/runtime/language.c +++ b/src/runtime/language.c @@ -12,11 +12,8 @@ void ts_language_table_entry(const TSLanguage *self, TSStateId state, result->action_count = 1; result->is_reusable = false; result->depends_on_lookahead = false; - if (symbol == ts_builtin_sym_error || - self->recovery_actions[symbol].type == TSParseActionTypeError) - result->actions = &ERROR_SHIFT_EXTRA; - else - result->actions = &self->recovery_actions[symbol]; + result->actions = (symbol == ts_builtin_sym_error) ? &ERROR_SHIFT_EXTRA + : &self->recovery_actions[symbol]; return; } diff --git a/src/runtime/language.h b/src/runtime/language.h index 6719c3da..8a7eb1ea 100644 --- a/src/runtime/language.h +++ b/src/runtime/language.h @@ -30,18 +30,15 @@ static inline const TSParseAction *ts_language_actions(const TSLanguage *self, return entry.actions; } -static inline TSParseAction ts_language_last_action(const TSLanguage *self, +static inline const TSParseAction *ts_language_last_action(const TSLanguage *self, TSStateId state, TSSymbol symbol) { TableEntry entry; ts_language_table_entry(self, state, symbol, &entry); - return entry.actions[entry.action_count - 1]; -} - -static inline bool ts_language_has_action(const TSLanguage *self, - TSStateId state, TSSymbol symbol) { - TSParseAction action = ts_language_last_action(self, state, symbol); - return action.type != TSParseActionTypeError; + if (entry.action_count) + return &entry.actions[entry.action_count - 1]; + else + return NULL; } static inline bool ts_language_is_reusable(const TSLanguage *self, diff --git a/src/runtime/parser.c b/src/runtime/parser.c index d0339445..3c304392 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -116,11 +116,12 @@ static BreakdownResult ts_parser__breakdown_top_of_stack(TSParser *self, if (last_child->symbol == ts_builtin_sym_error) { state = ts_parse_state_error; } else if (!last_child->extra) { - TSParseAction action = + const TSParseAction *action = ts_language_last_action(self->language, state, last_child->symbol); - assert(action.type == TSParseActionTypeShift || - action.type == TSParseActionTypeRecover); - state = action.to_state; + assert(action); + assert(action->type == TSParseActionTypeShift || + action->type == TSParseActionTypeRecover); + state = action->to_state; } LOG("breakdown_push sym:%s, size:%lu", SYM_NAME(last_child->symbol), @@ -224,12 +225,12 @@ static bool ts_parser__can_reuse(TSParser *self, StackVersion version, return false; } - TSParseAction action = entry.actions[entry.action_count - 1]; - if (action.type == TSParseActionTypeError) { + if (entry.action_count == 0) { LOG_ACTION("cant_reuse_unexpected tree:%s", SYM_NAME(tree->symbol)); return false; } + TSParseAction action = entry.actions[entry.action_count - 1]; if (tree->extra != action.extra) { LOG_ACTION("cant_reuse_extra tree:%s", SYM_NAME(tree->symbol)); return false; @@ -494,10 +495,11 @@ static Reduction ts_parser__reduce(TSParser *self, StackVersion version, parent->extra = true; new_state = state; } else { - TSParseAction action = ts_language_last_action(language, state, symbol); - assert(action.type == TSParseActionTypeShift || - action.type == TSParseActionTypeRecover); - new_state = action.to_state; + const TSParseAction *action = ts_language_last_action(language, state, symbol); + assert(action); + assert(action->type == TSParseActionTypeShift || + action->type == TSParseActionTypeRecover); + new_state = action->to_state; } CHECK(ts_parser__push(self, slice.version, parent, new_state)); @@ -533,33 +535,34 @@ static inline const TSParseAction *ts_parser__reductions_after_sequence( for (size_t i = 0; i < tree_count_below; i++) { TSTree *tree = trees_below->contents[trees_below->size - 1 - i]; - TSParseAction action = + const TSParseAction *action = ts_language_last_action(self->language, state, tree->symbol); - if (action.type != TSParseActionTypeShift) + if (!action || action->type != TSParseActionTypeShift) return NULL; - if (action.extra || tree->extra) + if (action->extra || tree->extra) continue; child_count++; - state = action.to_state; + state = action->to_state; } for (size_t i = 0; i < trees_above->size; i++) { TSTree *tree = trees_above->contents[i]; - TSParseAction action = + const TSParseAction *action = ts_language_last_action(self->language, state, tree->symbol); - if (action.type != TSParseActionTypeShift) + if (!action || action->type != TSParseActionTypeShift) return NULL; - if (action.extra || tree->extra) + if (action->extra || tree->extra) continue; child_count++; - state = action.to_state; + state = action->to_state; } const TSParseAction *actions = ts_language_actions(self->language, state, lookahead_symbol, count); - if (actions[*count - 1].type != TSParseActionTypeReduce) + if (*count > 0 && actions[*count - 1].type != TSParseActionTypeReduce) { (*count)--; + } while (*count > 0 && actions[0].child_count < child_count) { actions++; @@ -602,14 +605,14 @@ static StackIterateAction ts_parser__error_repair_callback( continue; } - TSParseAction repair_symbol_action = + const TSParseAction *repair_symbol_action = ts_language_last_action(self->language, state, repair->symbol); - if (repair_symbol_action.type != TSParseActionTypeShift) + if (!repair_symbol_action || repair_symbol_action->type != TSParseActionTypeShift) continue; - TSStateId state_after_repair = repair_symbol_action.to_state; - if (!ts_language_has_action(self->language, state_after_repair, - lookahead_symbol)) + TSStateId state_after_repair = repair_symbol_action->to_state; + if (!ts_language_last_action(self->language, state_after_repair, + lookahead_symbol)) continue; if (count_needed_below_error != last_repair_count) { @@ -930,7 +933,6 @@ static bool ts_parser__consume_lookahead(TSParser *self, StackVersion version, TSTree *lookahead) { for (;;) { TSStateId state = ts_stack_top_state(self->stack, version); - size_t error_repair_depth = ERROR_DEPTH_NONE; StackVersion last_reduction_version = STACK_VERSION_NONE; @@ -941,13 +943,6 @@ static bool ts_parser__consume_lookahead(TSParser *self, StackVersion version, for (size_t i = 0; i < action_count; i++) { TSParseAction action = actions[i]; - if (error_repair_depth != ERROR_DEPTH_NONE && - action.type == TSParseActionTypeReduce && - action.child_count > error_repair_depth) - continue; - - LOG_STACK(); - switch (action.type) { case TSParseActionTypeShift: { TSStateId next_state; @@ -965,6 +960,9 @@ static bool ts_parser__consume_lookahead(TSParser *self, StackVersion version, } case TSParseActionTypeReduce: { + if (action.child_count > error_repair_depth) + continue; + if (action.extra) { LOG_ACTION("reduce_extra"); } else { @@ -1014,10 +1012,9 @@ static bool ts_parser__consume_lookahead(TSParser *self, StackVersion version, CHECK(ts_parser__recover(self, version, action.to_state, lookahead)); return true; } - - case TSParseActionTypeError: { - } } + + LOG_STACK(); } if (last_reduction_version != STACK_VERSION_NONE) { @@ -1134,6 +1131,8 @@ TSTree *ts_parser_parse(TSParser *self, TSInput input, TSTree *previous_tree) { ts_tree_release(lookahead); goto error; } + + LOG_STACK(); } }