Syntax error sanity tests.

This commit is contained in:
Miguel Lechon
2021-03-14 11:24:26 +01:00
parent e4fbe7a81d
commit e3357f0759
17 changed files with 49 additions and 68 deletions
-7
View File
@@ -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
-8
View File
@@ -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
-7
View File
@@ -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
-1
View File
@@ -1 +0,0 @@
{
-1
View File
@@ -1 +0,0 @@
(
-1
View File
@@ -1 +0,0 @@
}
-1
View File
@@ -1 +0,0 @@
'
-2
View File
@@ -1,2 +0,0 @@
a:'''
multi-line text literal
-1
View File
@@ -1 +0,0 @@
/* asd
-1
View File
@@ -1 +0,0 @@
/* /* asd */
-1
View File
@@ -1 +0,0 @@
label:@tag {1, 2, 3} /* unterminated comment
-1
View File
@@ -1 +0,0 @@
#include <stdio.h>
-1
View File
@@ -1 +0,0 @@
@"tag" node
-2
View File
@@ -1,2 +0,0 @@
#namespace foo
{a,#b}
-25
View File
@@ -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;
}
+11 -6
View File
@@ -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;
+38 -2
View File
@@ -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 <stdio.h>", {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;
}