diff --git a/build.bat b/build.bat index 6b4dd68..2462dab 100644 --- a/build.bat +++ b/build.bat @@ -12,7 +12,6 @@ cl %compile_flags% ..\samples\static_site_generator\static_site_generator.c cl %compile_flags% ..\samples\output_parse\output_parse.c cl %compile_flags% ..\samples\c_code_generation.c cl %compile_flags% ..\samples\node_errors\node_errors.c -cl %compile_flags% ..\samples\syntax_errors\syntax_errors.c echo. echo ~~~ Build All Tests ~~~ cl %compile_flags% ..\tests\sanity_tests.c @@ -64,9 +63,3 @@ echo ~~~ Running Error Generation Sample ~~~ pushd build node_errors.exe %~dp0\samples\node_errors\node_errors.md popd - -echo. -echo ~~~ Running Syntax Error Detection and Reporting Sample ~~~ -pushd build -for /f "tokens=*" %%f in ('dir /s/b ..\samples\syntax_errors\*.md ^| sort') do syntax_errors.exe %%f -popd diff --git a/build.sh b/build.sh index db9df47..aa1f111 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,6 @@ $CC $compile_flags ../samples/static_site_generator/static_site_generator.c -o s $CC $compile_flags ../samples/output_parse/output_parse.c -o output_parse $CC $compile_flags ../samples/c_code_generation.c -o c_code_generation $CC $compile_flags ../samples/node_errors/node_errors.c -o node_errors -$CC $compile_flags ../samples/syntax_errors/syntax_errors.c -o syntax_errors echo echo ~~~ Build All Tests ~~~ $CC $compile_flags ../tests/sanity_tests.c -o sanity_tests @@ -64,10 +63,3 @@ echo ~~~ Running Error Generation Sample ~~~ pushd build ./node_errors ../samples/node_errors/node_errors.md popd - -echo -echo ~~~ Running Syntax Error Detection and Reporting Sample ~~~ -pushd build -./syntax_errors ../samples/syntax_errors/*.md -popd - diff --git a/build_with_clang.bat b/build_with_clang.bat index 9a2e496..155b415 100644 --- a/build_with_clang.bat +++ b/build_with_clang.bat @@ -14,7 +14,6 @@ clang %compile_flags% ..\samples\static_site_generator\static_site_generator.c - clang %compile_flags% ..\samples\output_parse\output_parse.c -o output_parse.exe clang %compile_flags% ..\samples\c_code_generation.c -o c_code_generation.exe clang %compile_flags% ..\samples\node_errors\node_errors.c -o node_errors.exe -clang %compile_flags% ..\samples\syntax_errors\syntax_errors.c -o syntax_errors.exe echo. echo ~~~ Build All Tests ~~~ clang %compile_flags% ..\tests\sanity_tests.c -o sanity_tests.exe @@ -66,9 +65,3 @@ echo ~~~ Running Error Generation Sample ~~~ pushd build node_errors.exe %~dp0\samples\node_errors\node_errors.md popd - -echo. -echo ~~~ Running Syntax Error Detection and Reporting Sample ~~~ -pushd build -for /f "tokens=*" %%f in ('dir /s/b ..\samples\syntax_errors\*.md ^| sort') do syntax_errors.exe %%f -popd diff --git a/samples/syntax_errors/00.md b/samples/syntax_errors/00.md deleted file mode 100644 index 98232c6..0000000 --- a/samples/syntax_errors/00.md +++ /dev/null @@ -1 +0,0 @@ -{ diff --git a/samples/syntax_errors/01.md b/samples/syntax_errors/01.md deleted file mode 100644 index 2d06f37..0000000 --- a/samples/syntax_errors/01.md +++ /dev/null @@ -1 +0,0 @@ -( diff --git a/samples/syntax_errors/02.md b/samples/syntax_errors/02.md deleted file mode 100644 index 5c34318..0000000 --- a/samples/syntax_errors/02.md +++ /dev/null @@ -1 +0,0 @@ -} diff --git a/samples/syntax_errors/03.md b/samples/syntax_errors/03.md deleted file mode 100644 index eef843b..0000000 --- a/samples/syntax_errors/03.md +++ /dev/null @@ -1 +0,0 @@ -' diff --git a/samples/syntax_errors/04.md b/samples/syntax_errors/04.md deleted file mode 100644 index 67997b3..0000000 --- a/samples/syntax_errors/04.md +++ /dev/null @@ -1,2 +0,0 @@ -a:''' -multi-line text literal diff --git a/samples/syntax_errors/05.md b/samples/syntax_errors/05.md deleted file mode 100644 index 141c53f..0000000 --- a/samples/syntax_errors/05.md +++ /dev/null @@ -1 +0,0 @@ -/* asd diff --git a/samples/syntax_errors/06.md b/samples/syntax_errors/06.md deleted file mode 100644 index feeef9e..0000000 --- a/samples/syntax_errors/06.md +++ /dev/null @@ -1 +0,0 @@ -/* /* asd */ diff --git a/samples/syntax_errors/07.md b/samples/syntax_errors/07.md deleted file mode 100644 index c818a8d..0000000 --- a/samples/syntax_errors/07.md +++ /dev/null @@ -1 +0,0 @@ -label:@tag {1, 2, 3} /* unterminated comment diff --git a/samples/syntax_errors/08.md b/samples/syntax_errors/08.md deleted file mode 100644 index 53c5fdf..0000000 --- a/samples/syntax_errors/08.md +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/samples/syntax_errors/09.md b/samples/syntax_errors/09.md deleted file mode 100644 index adb837b..0000000 --- a/samples/syntax_errors/09.md +++ /dev/null @@ -1 +0,0 @@ -@"tag" node diff --git a/samples/syntax_errors/10.md b/samples/syntax_errors/10.md deleted file mode 100644 index e1c81ff..0000000 --- a/samples/syntax_errors/10.md +++ /dev/null @@ -1,2 +0,0 @@ -#namespace foo -{a,#b} diff --git a/samples/syntax_errors/syntax_errors.c b/samples/syntax_errors/syntax_errors.c deleted file mode 100644 index c446baa..0000000 --- a/samples/syntax_errors/syntax_errors.c +++ /dev/null @@ -1,25 +0,0 @@ -// Sample code to demonstrate syntax error detection and reporting - -#include "md.h" -#include "md.c" - -int main(int argument_count, char **arguments) -{ - for(int i = 1; i < argument_count; i += 1) - { - MD_ParseResult parse = MD_ParseWholeFile(MD_S8CString(arguments[i])); - if(parse.first_error) - { - for(MD_Error *error = parse.first_error; error; error = error->next) - { - MD_OutputError(stderr, error); - } - } - else - { - printf("No error in file %s\n", arguments[i]); - } - } - - return 0; -} diff --git a/source/md_impl.c b/source/md_impl.c index 09ef4c4..9cea4b1 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -1106,7 +1106,7 @@ _MD_ComputeTextLiteralChop(MD_u32 bytes_to_skip, MD_u8 *beg, MD_u8 *end) // NOTE(mal): By counting the bytes to chop off text literals and encoding exact token.string and // token.outer_string we delegate the responsibility of generating errors to the parser // That way, we can avoid generating errors during peeks and save them for actual token - // consumption. That allows predictable error ordering. + // consumption. That allows more predictable error ordering. MD_u32 result = 0; MD_u8 *skip_end = beg + bytes_to_skip; MD_u8 *chop_beg = end - bytes_to_skip; @@ -1178,7 +1178,7 @@ MD_Parse_LexNext(MD_ParseCtx *ctx) { at += 2; token.kind = MD_TokenKind_Comment; - skip_n = chop_n = 2; + skip_n = 2; int counter = 1; for (;at < one_past_last && counter > 0; at += 1) { @@ -1196,6 +1196,10 @@ MD_Parse_LexNext(MD_ParseCtx *ctx) } } } + if(counter == 0) + { + chop_n = 2; + } } } if (token.kind == MD_TokenKind_Nil) goto symbol_lex; @@ -1438,7 +1442,7 @@ _MD_Error(MD_ParseCtx *ctx, MD_Node *node, MD_u8 *at, MD_b32 catastrophic, char if(!ctx->catastrophic_error || !prev_error || prev_error->catastrophic == 0) { MD_Error *error = _MD_PushArray(_MD_GetCtx(), MD_Error, 1); - error->node = node; + error->node = node ? node : MD_NilNode(); error->catastrophic = catastrophic; error->location = error_loc; error->filename = ctx->filename; @@ -1547,8 +1551,7 @@ _MD_CommentIsSyntacticallyCorrect(MD_Token comment_token) MD_String8 inner = comment_token.string; MD_String8 outer = comment_token.outer_string; MD_b32 incorrect = (MD_StringMatch(MD_StringPrefix(outer, 2), MD_S8Lit("/*"), 0) && // C-style comment - (!MD_StringMatch(MD_StringSuffix(outer, 2), MD_S8Lit("*/"), 0) || // Unfinished - inner.str + inner.size +2 != outer.str + outer.size)); // Internally unbalanced + (inner.str != outer.str + 2 || inner.str + inner.size != outer.str + outer.size - 2)); // Internally unbalanced result = !incorrect; return result; } @@ -1560,6 +1563,8 @@ _MD_ParseOneNode(MD_ParseCtx *ctx) MD_ParseResult result = MD_ZERO_STRUCT; result.node = MD_NilNode(); + + MD_Error *ctx_last_error = ctx->last_error; MD_Token token; _MD_MemoryZero(&token, sizeof(token)); @@ -1722,7 +1727,7 @@ _MD_ParseOneNode(MD_ParseCtx *ctx) } result.bytes_parsed = (MD_u64)(ctx->at - at_first); - + result.first_error = ctx_last_error ? ctx_last_error->next : 0; if(!MD_NodeIsNil(result.node)) { result.node->first_tag = first_tag; diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index 43d2af2..3300755 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -444,8 +444,44 @@ int main(void) MD_StringMatch(parse.node->comment_after, MD_S8Lit(""), 0)); } } - } - + + Test("Syntax Errors") + { + struct { char *s; int columns[2]; } tests[] = { + {"{", {1}}, + {"}", {1}}, + {"'", {1}}, + {"a:'''\nmulti-line text literal", {3}}, + {"/* foo", {1}}, + {"label:@tag {1, 2, 3} /* /* unterminated comment */", {8, 22}}, + {"#include ", {2}}, + {"@\"tag\" node", {2}}, + {"{a,,#b}", {4, 5}}, + }; + + int max_error_count = MD_ArrayCount(tests[0].columns); + + for(int i_test = 0; i_test < MD_ArrayCount(tests); ++i_test) + { + MD_ParseResult parse = MD_ParseWholeString(MD_S8Lit("test.md"), MD_S8CString(tests[i_test].s)); + + MD_b32 columns_match = 1; + { + MD_Error *e = parse.first_error; + for(int i_error = 0; i_error < max_error_count && tests[i_test].columns[i_error]; ++i_error) + { + if(!e || e->location.column != tests[i_test].columns[i_error]) + { + columns_match = 0; + break; + } + e = e->next; + } + } + TestResult(columns_match); + } + } + return 0; } \ No newline at end of file