diff --git a/mpc.c b/mpc.c index 37a51ff..705c26c 100644 --- a/mpc.c +++ b/mpc.c @@ -662,6 +662,7 @@ static int mpc_input_boundary(mpc_input_t* i) { "0123456789_"; char peek = mpc_input_peekc(i); + if (strchr(word, i->last) && peek == '\0') { return 1; } if (strchr(word, peek) && !strchr(word, i->last)) { return 1; } if (!strchr(word, peek) && strchr(word, i->last)) { return 1; } @@ -2435,7 +2436,7 @@ void mpc_print(mpc_parser_t *p) { ** */ -int mpc_unmatch(mpc_parser_t *p, const char *s, void *d, +int mpc_test_fail(mpc_parser_t *p, const char *s, void *d, int(*tester)(void*, void*), mpc_dtor_t destructor, void(*printer)(void*)) { @@ -2458,7 +2459,7 @@ int mpc_unmatch(mpc_parser_t *p, const char *s, void *d, } -int mpc_match(mpc_parser_t *p, const char *s, void *d, +int mpc_test_pass(mpc_parser_t *p, const char *s, void *d, int(*tester)(void*, void*), mpc_dtor_t destructor, void(*printer)(void*)) { diff --git a/mpc.h b/mpc.h index 0015a58..011ee6d 100644 --- a/mpc.h +++ b/mpc.h @@ -312,14 +312,16 @@ mpc_err_t *mpca_lang_contents(int flags, const char *filename, ...); void mpc_print(mpc_parser_t *p); -int mpc_unmatch(mpc_parser_t *p, const char *s, void *d, - int(*tester)(void*, void*), - mpc_dtor_t destructor, - void(*printer)(void*)); - -int mpc_match(mpc_parser_t *p, const char *s, void *d, +int mpc_test_pass(mpc_parser_t *p, const char *s, void *d, int(*tester)(void*, void*), mpc_dtor_t destructor, void(*printer)(void*)); +int mpc_test_fail(mpc_parser_t *p, const char *s, void *d, + int(*tester)(void*, void*), + mpc_dtor_t destructor, + void(*printer)(void*)); + + + #endif diff --git a/tests/core.c b/tests/core.c index 9bccfff..ec40b7f 100644 --- a/tests/core.c +++ b/tests/core.c @@ -21,13 +21,13 @@ void test_ident(void) { free ); - PT_ASSERT(mpc_match(Ident, "test", "test", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(Ident, " blah", "", string_eq, free, string_print)); - PT_ASSERT(mpc_match(Ident, "anoth21er", "anoth21er", string_eq, free, string_print)); - PT_ASSERT(mpc_match(Ident, "du__de", "du__de", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(Ident, "some spaces", "", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(Ident, "", "", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(Ident, "18nums", "", string_eq, free, string_print)); + PT_ASSERT(mpc_test_pass(Ident, "test", "test", string_eq, free, string_print)); + PT_ASSERT(mpc_test_fail(Ident, " blah", "", string_eq, free, string_print)); + PT_ASSERT(mpc_test_pass(Ident, "anoth21er", "anoth21er", string_eq, free, string_print)); + PT_ASSERT(mpc_test_pass(Ident, "du__de", "du__de", string_eq, free, string_print)); + PT_ASSERT(mpc_test_fail(Ident, "some spaces", "", string_eq, free, string_print)); + PT_ASSERT(mpc_test_fail(Ident, "", "", string_eq, free, string_print)); + PT_ASSERT(mpc_test_fail(Ident, "18nums", "", string_eq, free, string_print)); mpc_delete(Ident); @@ -36,11 +36,7 @@ void test_ident(void) { void test_maths(void) { mpc_parser_t *Expr, *Factor, *Term, *Maths; - int r0 = 1; - int r1 = 5; - int r2 = 13; - int r3 = 0; - int r4 = 2; + int r0 = 1, r1 = 5, r2 = 13, r3 = 0, r4 = 2; Expr = mpc_new("expr"); Factor = mpc_new("factor"); @@ -64,11 +60,11 @@ void test_maths(void) { mpc_define(Maths, mpc_whole(Expr, free)); - PT_ASSERT(mpc_match(Maths, "1", &r0, int_eq, free, int_print)); - PT_ASSERT(mpc_match(Maths, "(5)", &r1, int_eq, free, int_print)); - PT_ASSERT(mpc_match(Maths, "(4*2)+5", &r2, int_eq, free, int_print)); - PT_ASSERT(mpc_unmatch(Maths, "a", &r3, int_eq, free, int_print)); - PT_ASSERT(mpc_unmatch(Maths, "2b+4", &r4, int_eq, free, int_print)); + PT_ASSERT(mpc_test_pass(Maths, "1", &r0, int_eq, free, int_print)); + PT_ASSERT(mpc_test_pass(Maths, "(5)", &r1, int_eq, free, int_print)); + PT_ASSERT(mpc_test_pass(Maths, "(4*2)+5", &r2, int_eq, free, int_print)); + PT_ASSERT(mpc_test_fail(Maths, "a", &r3, int_eq, free, int_print)); + PT_ASSERT(mpc_test_fail(Maths, "2b+4", &r4, int_eq, free, int_print)); mpc_cleanup(4, Expr, Factor, Term, Maths); } diff --git a/tests/grammar.c b/tests/grammar.c index b1d562d..2f8709b 100644 --- a/tests/grammar.c +++ b/tests/grammar.c @@ -43,11 +43,11 @@ void test_grammar(void) { mpc_ast_new("char", "+"), mpc_ast_new("product|value|regex", "5")); - PT_ASSERT(mpc_match(Maths, " 24 ", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); - PT_ASSERT(mpc_match(Maths, "(5)", t1, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); - PT_ASSERT(mpc_match(Maths, "(4 * 2 * 11 + 2) + 5", t2, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); - PT_ASSERT(mpc_unmatch(Maths, "a", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); - PT_ASSERT(mpc_unmatch(Maths, "2b+4", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); + PT_ASSERT(mpc_test_pass(Maths, " 24 ", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); + PT_ASSERT(mpc_test_pass(Maths, "(5)", t1, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); + PT_ASSERT(mpc_test_pass(Maths, "(4 * 2 * 11 + 2) + 5", t2, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); + PT_ASSERT(mpc_test_fail(Maths, "a", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); + PT_ASSERT(mpc_test_fail(Maths, "2b+4", t0, (int(*)(void*,void*))mpc_ast_eq, (mpc_dtor_t)mpc_ast_delete, (void(*)(void*))mpc_ast_print)); mpc_ast_delete(t0); mpc_ast_delete(t1); @@ -85,7 +85,7 @@ void test_language_file(void) { Value = mpc_new("value"); Maths = mpc_new("maths"); - mpca_lang_contents(MPCA_LANG_DEFAULT,"./tests/maths.grammar", Expr, Prod, Value, Maths); + mpca_lang_contents(MPCA_LANG_DEFAULT, "./tests/maths.grammar", Expr, Prod, Value, Maths); mpc_cleanup(4, Expr, Prod, Value, Maths); diff --git a/tests/regex.c b/tests/regex.c index ddd6ad1..70ddedf 100644 --- a/tests/regex.c +++ b/tests/regex.c @@ -7,9 +7,17 @@ static int string_eq(void* x, void* y) { return (strcmp(x, y) == 0); } static void string_print(void* x) { printf("'%s'", (char*)x); } +int regex_test_pass(mpc_parser_t *p, char* value, char* match) { + return mpc_test_pass(p, value, match, string_eq, free, string_print); +} + +int regex_test_fail(mpc_parser_t *p, char* value, char* match) { + return mpc_test_fail(p, value, match, string_eq, free, string_print); +} + void test_regex_basic(void) { - mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5, *re6, *re7; + mpc_parser_t *re0, *re1, *re2, *re3, *re4, *re5; re0 = mpc_re("abc|bcd"); re1 = mpc_re("abc|bcd|e"); @@ -17,24 +25,16 @@ void test_regex_basic(void) { re3 = mpc_re("abc(abdd)?"); re4 = mpc_re("ab|c(abdd)?"); re5 = mpc_re("abc(ab|dd)+g$"); - re6 = mpc_re("\"(\\\\.|[^\"])*\""); - re7 = mpc_re(";[^\\n\\r]*"); - PT_ASSERT(mpc_match(re0, "abc", "abc", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re0, "bcd", "bcd", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(re0, "bc", "bc", string_eq, free, string_print)); - PT_ASSERT(mpc_unmatch(re0, "ab", "ab", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re1, "e", "e", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re2, "abc", "abc", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re2, "abcabab", "abcabab", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re2, "abcababd", "abcabab", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re5, "abcddg", "abcddg", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re6, "\"there\"", "\"there\"", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re6, "\"hello\"", "\"hello\"", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re6, "\"i am dan\"", "\"i am dan\"", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re6, "\"i a\\\"m dan\"", "\"i a\\\"m dan\"", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re7, ";comment", ";comment", string_eq, free, string_print)); - PT_ASSERT(mpc_match(re7, ";i am the\nman", ";i am the", string_eq, free, string_print)); + PT_ASSERT(regex_test_pass(re0, "abc", "abc")); + PT_ASSERT(regex_test_pass(re0, "bcd", "bcd")); + PT_ASSERT(regex_test_fail(re0, "bc", "bc")); + PT_ASSERT(regex_test_fail(re0, "ab", "ab")); + PT_ASSERT(regex_test_pass(re1, "e", "e")); + PT_ASSERT(regex_test_pass(re2, "abc", "abc")); + PT_ASSERT(regex_test_pass(re2, "abcabab", "abcabab")); + PT_ASSERT(regex_test_pass(re2, "abcababd", "abcabab")); + PT_ASSERT(regex_test_pass(re5, "abcddg", "abcddg")); mpc_delete(re0); mpc_delete(re1); @@ -42,11 +42,42 @@ void test_regex_basic(void) { mpc_delete(re3); mpc_delete(re4); mpc_delete(re5); - mpc_delete(re6); - mpc_delete(re7); } +void test_regex_boundary(void) { + + mpc_parser_t *re0, *re1, *re2; + + re0 = mpc_re("\\bfoo\\b"); + re1 = mpc_re("(w| )?\\bfoo\\b"); + re2 = mpc_re("py\\B.*"); + + PT_ASSERT(regex_test_pass(re0, "foo", "foo")); + PT_ASSERT(regex_test_pass(re0, "foo.", "foo")); + PT_ASSERT(regex_test_pass(re0, "foo)", "foo")); + PT_ASSERT(regex_test_pass(re0, "foo baz", "foo")); + + PT_ASSERT(regex_test_fail(re0, "foobar", "foo")); + PT_ASSERT(regex_test_fail(re0, "foo3", "foo")); + + PT_ASSERT(regex_test_pass(re1, "foo", "foo")); + PT_ASSERT(regex_test_pass(re1, " foo", " foo")); + PT_ASSERT(regex_test_fail(re1, "wfoo", "foo")); + + PT_ASSERT(regex_test_pass(re2, "python", "python")); + PT_ASSERT(regex_test_pass(re2, "py3", "py3")); + PT_ASSERT(regex_test_pass(re2, "py2", "py2")); + PT_ASSERT(regex_test_fail(re2, "py", "py")); + PT_ASSERT(regex_test_fail(re2, "py.", "py.")); + PT_ASSERT(regex_test_fail(re2, "py!", "py!")); + + mpc_delete(re0); + mpc_delete(re1); + mpc_delete(re2); + +} + void test_regex_range(void) { mpc_parser_t *re0, *re1, *re2, *re3; @@ -65,7 +96,34 @@ void test_regex_range(void) { } +void test_regex_string(void) { + + mpc_parser_t *re0 = mpc_re("\"(\\\\.|[^\"])*\""); + + PT_ASSERT(regex_test_pass(re0, "\"there\"", "\"there\"")); + PT_ASSERT(regex_test_pass(re0, "\"hello\"", "\"hello\"")); + PT_ASSERT(regex_test_pass(re0, "\"i am dan\"", "\"i am dan\"")); + PT_ASSERT(regex_test_pass(re0, "\"i a\\\"m dan\"", "\"i a\\\"m dan\"")); + + mpc_delete(re0); + +} + +void test_regex_lisp_comment(void) { + + mpc_parser_t *re0 = mpc_re(";[^\\n\\r]*"); + + PT_ASSERT(regex_test_pass(re0, ";comment", ";comment")); + PT_ASSERT(regex_test_pass(re0, ";i am the\nman", ";i am the")); + + mpc_delete(re0); + +} + void suite_regex(void) { pt_add_test(test_regex_basic, "Test Regex Basic", "Suite Regex"); pt_add_test(test_regex_range, "Test Regex Range", "Suite Regex"); + pt_add_test(test_regex_string, "Test Regex String", "Suite Regex"); + pt_add_test(test_regex_lisp_comment, "Test Regex Lisp Comment", "Suite Regex"); + pt_add_test(test_regex_boundary, "Test Regex Boundary", "Suite Regex"); }