core.c (7011B)
1 #include "ptest.h" 2 #include "../mpc.h" 3 4 #include <stdlib.h> 5 #include <string.h> 6 7 static int int_eq(const void* x, const void* y) { return (*(int*)x == *(int*)y); } 8 static void int_print(const void* x) { printf("'%i'", *((int*)x)); } 9 static int streq(const void* x, const void* y) { return (strcmp(x, y) == 0); } 10 static void strprint(const void* x) { printf("'%s'", (char*)x); } 11 12 void test_ident(void) { 13 14 /* ^[a-zA-Z_][a-zA-Z0-9_]*$ */ 15 16 mpc_parser_t* Ident = mpc_whole( 17 mpc_and(2, mpcf_strfold, 18 mpc_or(2, mpc_alpha(), mpc_underscore()), 19 mpc_many1(mpcf_strfold, mpc_or(3, mpc_alpha(), mpc_underscore(), mpc_digit())), 20 free), 21 free 22 ); 23 24 PT_ASSERT(mpc_test_pass(Ident, "test", "test", streq, free, strprint)); 25 PT_ASSERT(mpc_test_fail(Ident, " blah", "", streq, free, strprint)); 26 PT_ASSERT(mpc_test_pass(Ident, "anoth21er", "anoth21er", streq, free, strprint)); 27 PT_ASSERT(mpc_test_pass(Ident, "du__de", "du__de", streq, free, strprint)); 28 PT_ASSERT(mpc_test_fail(Ident, "some spaces", "", streq, free, strprint)); 29 PT_ASSERT(mpc_test_fail(Ident, "", "", streq, free, strprint)); 30 PT_ASSERT(mpc_test_fail(Ident, "18nums", "", streq, free, strprint)); 31 32 mpc_delete(Ident); 33 34 } 35 36 static mpc_val_t *mpcf_maths(int n, mpc_val_t **xs) { 37 int **vs = (int**)xs; 38 (void) n; 39 40 switch(((char*)xs[1])[0]) 41 { 42 case '*': { *vs[0] *= *vs[2]; }; break; 43 case '/': { *vs[0] /= *vs[2]; }; break; 44 case '%': { *vs[0] %= *vs[2]; }; break; 45 case '+': { *vs[0] += *vs[2]; }; break; 46 case '-': { *vs[0] -= *vs[2]; }; break; 47 default: break; 48 } 49 50 free(xs[1]); free(xs[2]); 51 52 return xs[0]; 53 } 54 55 void test_maths(void) { 56 57 mpc_parser_t *Expr, *Factor, *Term, *Maths; 58 int r0 = 1, r1 = 5, r2 = 13, r3 = 0, r4 = 2; 59 60 Expr = mpc_new("expr"); 61 Factor = mpc_new("factor"); 62 Term = mpc_new("term"); 63 Maths = mpc_new("maths"); 64 65 mpc_define(Expr, mpc_or(2, 66 mpc_and(3, mpcf_maths, Factor, mpc_oneof("+-"), Factor, free, free), 67 Factor 68 )); 69 70 mpc_define(Factor, mpc_or(2, 71 mpc_and(3, mpcf_maths, Term, mpc_oneof("*/"), Term, free, free), 72 Term 73 )); 74 75 mpc_define(Term, mpc_or(2, 76 mpc_int(), 77 mpc_parens(Expr, free) 78 )); 79 80 mpc_define(Maths, mpc_whole(Expr, free)); 81 82 PT_ASSERT(mpc_test_pass(Maths, "1", &r0, int_eq, free, int_print)); 83 PT_ASSERT(mpc_test_pass(Maths, "(5)", &r1, int_eq, free, int_print)); 84 PT_ASSERT(mpc_test_pass(Maths, "(4*2)+5", &r2, int_eq, free, int_print)); 85 PT_ASSERT(mpc_test_pass(Maths, "4*2+5", &r2, int_eq, free, int_print)); 86 PT_ASSERT(mpc_test_fail(Maths, "a", &r3, int_eq, free, int_print)); 87 PT_ASSERT(mpc_test_fail(Maths, "2b+4", &r4, int_eq, free, int_print)); 88 89 mpc_cleanup(4, Expr, Factor, Term, Maths); 90 } 91 92 void test_strip(void) { 93 94 mpc_parser_t *Stripperl = mpc_apply(mpc_many(mpcf_strfold, mpc_any()), mpcf_strtriml); 95 mpc_parser_t *Stripperr = mpc_apply(mpc_many(mpcf_strfold, mpc_any()), mpcf_strtrimr); 96 mpc_parser_t *Stripper = mpc_apply(mpc_many(mpcf_strfold, mpc_any()), mpcf_strtrim); 97 98 PT_ASSERT(mpc_test_pass(Stripperl, " asdmlm dasd ", "asdmlm dasd ", streq, free, strprint)); 99 PT_ASSERT(mpc_test_pass(Stripperr, " asdmlm dasd ", " asdmlm dasd", streq, free, strprint)); 100 PT_ASSERT(mpc_test_pass(Stripper, " asdmlm dasd ", "asdmlm dasd", streq, free, strprint)); 101 102 mpc_delete(Stripperl); 103 mpc_delete(Stripperr); 104 mpc_delete(Stripper); 105 106 } 107 108 void test_repeat(void) { 109 110 int success; 111 mpc_result_t r; 112 mpc_parser_t *p = mpc_count(3, mpcf_strfold, mpc_digit(), free); 113 114 success = mpc_parse("test", "046", p, &r); 115 PT_ASSERT(success); 116 PT_ASSERT_STR_EQ(r.output, "046"); 117 free(r.output); 118 119 success = mpc_parse("test", "046aa", p, &r); 120 PT_ASSERT(success); 121 PT_ASSERT_STR_EQ(r.output, "046"); 122 free(r.output); 123 124 success = mpc_parse("test", "04632", p, &r); 125 PT_ASSERT(success); 126 PT_ASSERT_STR_EQ(r.output, "046"); 127 free(r.output); 128 129 success = mpc_parse("test", "04", p, &r); 130 PT_ASSERT(!success); 131 mpc_err_delete(r.error); 132 133 mpc_delete(p); 134 135 } 136 137 void test_copy(void) { 138 139 int success; 140 mpc_result_t r; 141 mpc_parser_t* p = mpc_or(2, mpc_char('a'), mpc_char('b')); 142 mpc_parser_t* q = mpc_and(2, mpcf_strfold, p, mpc_copy(p), free); 143 144 success = mpc_parse("test", "aa", q, &r); 145 PT_ASSERT(success); 146 PT_ASSERT_STR_EQ(r.output, "aa"); 147 free(r.output); 148 149 success = mpc_parse("test", "bb", q, &r); 150 PT_ASSERT(success); 151 PT_ASSERT_STR_EQ(r.output, "bb"); 152 free(r.output); 153 154 success = mpc_parse("test", "ab", q, &r); 155 PT_ASSERT(success); 156 PT_ASSERT_STR_EQ(r.output, "ab"); 157 free(r.output); 158 159 success = mpc_parse("test", "ba", q, &r); 160 PT_ASSERT(success); 161 PT_ASSERT_STR_EQ(r.output, "ba"); 162 free(r.output); 163 164 success = mpc_parse("test", "c", p, &r); 165 PT_ASSERT(!success); 166 mpc_err_delete(r.error); 167 168 mpc_delete(mpc_copy(p)); 169 mpc_delete(mpc_copy(q)); 170 171 mpc_delete(q); 172 173 } 174 175 static int line_count = 0; 176 177 static mpc_val_t* read_line(mpc_val_t* line) { 178 line_count++; 179 return line; 180 } 181 182 void test_reader(void) { 183 184 mpc_parser_t* Line = mpc_many( 185 mpcf_strfold, 186 mpc_apply(mpc_re("[^\\n]*(\\n|$)"), read_line)); 187 188 line_count = 0; 189 190 PT_ASSERT(mpc_test_pass(Line, 191 "hello\nworld\n\nthis\nis\ndan", 192 "hello\nworld\n\nthis\nis\ndan", streq, free, strprint)); 193 194 PT_ASSERT(line_count == 6); 195 196 line_count = 0; 197 198 PT_ASSERT(mpc_test_pass(Line, 199 "abcHVwufvyuevuy3y436782\n\n\nrehre\nrew\n-ql.;qa\neg", 200 "abcHVwufvyuevuy3y436782\n\n\nrehre\nrew\n-ql.;qa\neg", streq, free, strprint)); 201 202 PT_ASSERT(line_count == 7); 203 204 mpc_delete(Line); 205 206 } 207 208 static int token_count = 0; 209 210 static mpc_val_t *print_token(mpc_val_t *x) { 211 /*printf("Token: '%s'\n", (char*)x);*/ 212 token_count++; 213 return x; 214 } 215 216 void test_tokens(void) { 217 218 mpc_parser_t* Tokens = mpc_many( 219 mpcf_strfold, 220 mpc_apply(mpc_strip(mpc_re("\\s*([a-zA-Z_]+|[0-9]+|,|\\.|:)")), print_token)); 221 222 token_count = 0; 223 224 PT_ASSERT(mpc_test_pass(Tokens, 225 " hello 4352 , \n foo.bar \n\n test:ing ", 226 "hello4352,foo.bartest:ing", streq, free, strprint)); 227 228 PT_ASSERT(token_count == 9); 229 230 mpc_delete(Tokens); 231 232 } 233 234 void test_eoi(void) { 235 236 mpc_parser_t* Line = mpc_re("[^\\n]*$"); 237 238 PT_ASSERT(mpc_test_pass(Line, "blah", "blah", streq, free, strprint)); 239 PT_ASSERT(mpc_test_pass(Line, "blah\n", "blah\n", streq, free, strprint)); 240 241 mpc_delete(Line); 242 243 } 244 245 void suite_core(void) { 246 pt_add_test(test_ident, "Test Ident", "Suite Core"); 247 pt_add_test(test_maths, "Test Maths", "Suite Core"); 248 pt_add_test(test_strip, "Test Strip", "Suite Core"); 249 pt_add_test(test_repeat, "Test Repeat", "Suite Core"); 250 pt_add_test(test_copy, "Test Copy", "Suite Core"); 251 pt_add_test(test_reader, "Test Reader", "Suite Core"); 252 pt_add_test(test_tokens, "Test Tokens", "Suite Core"); 253 pt_add_test(test_eoi, "Test EOI", "Suite Core"); 254 }