tree-sitter/src/runtime/language.c
Max Brunsfeld 1e353381ff Don't create error node in lexer unless token is completely invalid
Before, any syntax error would cause the lexer to create an error
leaf node. This could happen even with a valid input, if the parse
stack had split and one particular version of the parse stack
failed to parse.

Now, an error leaf node is only created when the lexer cannot understand
part of the input stream at all. When a normal syntax error occurs,
the lexer just returns a token that is outside of the expected token
set, and the parser handles the unexpected token.
2016-05-26 14:15:10 -07:00

58 lines
1.9 KiB
C

#include "tree_sitter/parser.h"
#include "runtime/language.h"
#include "runtime/tree.h"
static const TSParseAction ERROR_SHIFT_EXTRA = {
.type = TSParseActionTypeShift, .extra = true,
};
const TSParseAction *ts_language_actions(const TSLanguage *self, TSStateId state,
TSSymbol symbol, size_t *count) {
if (state == ts_parse_state_error) {
*count = 1;
return (symbol == ts_builtin_sym_error) ? &ERROR_SHIFT_EXTRA
: &self->recovery_actions[symbol];
}
size_t action_index = 0;
if (symbol != ts_builtin_sym_error)
action_index = self->parse_table[state * self->symbol_count + symbol];
*count = self->parse_actions[action_index].count;
const TSParseActionEntry *entry = self->parse_actions + action_index + 1;
return (const TSParseAction *)entry;
}
TSParseAction ts_language_last_action(const TSLanguage *self, TSStateId state,
TSSymbol sym) {
size_t count;
const TSParseAction *actions = ts_language_actions(self, state, sym, &count);
return actions[count - 1];
}
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;
}
size_t ts_language_symbol_count(const TSLanguage *language) {
return language->symbol_count;
}
TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *language,
TSSymbol symbol) {
if (symbol == ts_builtin_sym_error)
return (TSSymbolMetadata){
.visible = true, .named = true, .extra = false, .structural = true,
};
else
return language->symbol_metadata[symbol];
}
const char *ts_language_symbol_name(const TSLanguage *language, TSSymbol symbol) {
if (symbol == ts_builtin_sym_error)
return "ERROR";
else
return language->symbol_names[symbol];
}