diff --git a/examples/grammars/json.hpp b/examples/grammars/json.hpp index a57a2db7..d126fad3 100644 --- a/examples/grammars/json.hpp +++ b/examples/grammars/json.hpp @@ -33,7 +33,7 @@ namespace test_grammars { _sym("right_brace"), }) }, { "array", seq({ _sym("left_bracket"), - comma_sep(sym("value")), + comma_sep(err(sym("value"))), _sym("right_bracket"), }) }, { "string", pattern("\"([^\"]|\\\\\")+\"") }, { "number", pattern("\\d+") }, diff --git a/examples/parsers/json.c b/examples/parsers/json.c index ce03de93..b5c66399 100644 --- a/examples/parsers/json.c +++ b/examples/parsers/json.c @@ -42,8 +42,16 @@ static const ts_symbol * ts_recover(ts_state state, ts_state *to_state, size_t * RECOVER(47, 2, EXPECT({ts_sym_comma, ts_sym_right_brace})); case 13: RECOVER(44, 2, EXPECT({ts_sym_comma, ts_sym_right_brace})); + case 19: + RECOVER(21, 2, EXPECT({ts_sym_comma, ts_sym_right_bracket})); + case 22: + RECOVER(23, 2, EXPECT({ts_sym_comma, ts_sym_right_bracket})); case 25: RECOVER(32, 2, EXPECT({ts_sym_comma, ts_sym_right_brace})); + case 35: + RECOVER(36, 2, EXPECT({ts_sym_comma, ts_sym_right_bracket})); + case 55: + RECOVER(56, 2, EXPECT({ts_sym_comma, ts_sym_right_bracket})); default: RECOVER(0, 0, EXPECT({})); } @@ -468,8 +476,10 @@ PARSE_FN() { SHIFT(35); case ts_sym_right_bracket: SHIFT(42); + case ts_builtin_sym_error: + SHIFT(21); default: - PARSE_ERROR(8, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket})); + PARSE_ERROR(9, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket, ts_builtin_sym_error})); } case 20: SET_LEX_STATE(6); @@ -510,8 +520,10 @@ PARSE_FN() { SHIFT(25); case ts_sym_left_bracket: SHIFT(35); + case ts_builtin_sym_error: + SHIFT(23); default: - PARSE_ERROR(7, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket})); + PARSE_ERROR(8, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_builtin_sym_error})); } case 23: SET_LEX_STATE(6); @@ -662,8 +674,10 @@ PARSE_FN() { SHIFT(35); case ts_sym_right_bracket: SHIFT(39); + case ts_builtin_sym_error: + SHIFT(36); default: - PARSE_ERROR(8, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket})); + PARSE_ERROR(9, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket, ts_builtin_sym_error})); } case 36: SET_LEX_STATE(6); @@ -864,8 +878,10 @@ PARSE_FN() { SHIFT(35); case ts_sym_right_bracket: SHIFT(59); + case ts_builtin_sym_error: + SHIFT(56); default: - PARSE_ERROR(8, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket})); + PARSE_ERROR(9, EXPECT({ts_sym_array, ts_sym_number, ts_sym_object, ts_sym_string, ts_sym_value, ts_sym_left_brace, ts_sym_left_bracket, ts_sym_right_bracket, ts_builtin_sym_error})); } case 56: SET_LEX_STATE(6); diff --git a/spec/runtime/json_spec.cpp b/spec/runtime/json_spec.cpp index ab8e241a..4d9ddda3 100644 --- a/spec/runtime/json_spec.cpp +++ b/spec/runtime/json_spec.cpp @@ -55,9 +55,17 @@ describe("json", []() { AssertThat(string(ts_document_string(doc)), Equals("(ERROR)")); }); - it("reports errors inside of nested objects", [&]() { + it("reports errors inside of arrays and objects", [&]() { ts_document_set_text(doc, "{ \"key1\": 1, 5 }"); AssertThat(string(ts_document_string(doc)), Equals("(value (object (string) (value (number)) (ERROR)))")); + + ts_document_set_text(doc, "[1,,2]"); + AssertThat(string(ts_document_string(doc)), Equals("(value (array (value (number)) (ERROR) (value (number))))")); + }); + + it("reports errors in nested objects", [&]() { + ts_document_set_text(doc, "{ \"key1\": { \"key2\": 1, 2 }, [, \"key3\": 3 }"); + AssertThat(string(ts_document_string(doc)), Equals("(value (object (string) (value (object (string) (value (number)) (ERROR))) (ERROR) (string) (value (number))))")); }); }); }); diff --git a/todo.md b/todo.md index a8953b46..2d343711 100644 --- a/todo.md +++ b/todo.md @@ -2,7 +2,6 @@ TODO ==== ## batch parsing -- error handling: keep going when errors are encountered and put error nodes into the AST - more example grammars: - go - javascript