Do not insert missing tokens if halt_on_error option is passed

This commit is contained in:
Max Brunsfeld 2018-01-24 14:04:55 -08:00
parent 3bda284656
commit 46dcd53090
2 changed files with 38 additions and 15 deletions

View file

@ -208,10 +208,9 @@ static bool parser__better_version_exists(Parser *self, StackVersion version,
return false;
}
static bool parser__condense_stack(Parser *self) {
static unsigned parser__condense_stack(Parser *self) {
bool made_changes = false;
unsigned min_error_cost = UINT_MAX;
bool all_versions_have_error = true;
for (StackVersion i = 0; i < ts_stack_version_count(self->stack); i++) {
if (ts_stack_is_halted(self->stack, i)) {
ts_stack_remove_version(self->stack, i);
@ -225,8 +224,9 @@ static bool parser__condense_stack(Parser *self) {
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, i),
.is_in_error = ts_stack_top_state(self->stack, i) == ERROR_STATE,
};
if (!status_i.is_in_error) all_versions_have_error = false;
if (status_i.cost < min_error_cost) min_error_cost = status_i.cost;
if (!status_i.is_in_error && status_i.cost < min_error_cost) {
min_error_cost = status_i.cost;
}
for (StackVersion j = 0; j < i; j++) {
ErrorStatus status_j = {
@ -291,9 +291,7 @@ static bool parser__condense_stack(Parser *self) {
LOG_STACK();
}
return
(all_versions_have_error && ts_stack_version_count(self->stack) > 0) ||
(self->finished_tree && self->finished_tree->error_cost < min_error_cost);
return min_error_cost;
}
static void parser__restore_external_scanner(Parser *self, Tree *external_token) {
@ -1239,14 +1237,12 @@ Tree *parser_parse(Parser *self, TSInput input, Tree *old_tree, bool halt_on_err
self->reusable_node = reusable_node;
bool should_halt = parser__condense_stack(self);
if (should_halt) {
if (self->finished_tree) {
break;
} else if (halt_on_error) {
parser__halt_parse(self);
break;
}
unsigned min_error_cost = parser__condense_stack(self);
if (self->finished_tree && self->finished_tree->error_cost < min_error_cost) {
break;
} else if (halt_on_error && min_error_cost > 0) {
parser__halt_parse(self);
break;
}
self->in_ambiguity = version > 1;

View file

@ -439,6 +439,33 @@ describe("Document", [&]() {
AssertThat(ts_node_end_byte(root), Equals(input_string.size()));
});
it("does not insert missing tokens if the halt_on_error flag is set", [&]() {
string input_string = "[1, null, 3";
ts_document_set_language(document, load_real_language("json"));
ts_document_set_input_string(document, input_string.c_str());
TSParseOptions options = {};
options.changed_ranges = nullptr;
options.halt_on_error = false;
ts_document_parse_with_options(document, options);
root = ts_document_root_node(document);
assert_node_string_equals(
root,
"(value (array (number) (null) (number) (MISSING)))");
ts_document_invalidate(document);
options.halt_on_error = true;
ts_document_parse_with_options(document, options);
root = ts_document_root_node(document);
assert_node_string_equals(
root,
"(ERROR (number) (null) (number))");
AssertThat(ts_node_end_byte(root), Equals(input_string.size()));
});
it("can parse valid code with the halt_on_error flag set", [&]() {
string input_string = "[1, null, 3]";
ts_document_set_language(document, load_real_language("json"));