/* retoor */ #include "../include/lexer.h" #include #include #include static int tests_passed = 0; static int tests_failed = 0; #define TEST(name) static void test_##name(void) #define RUN_TEST(name) do { \ printf(" %s... ", #name); \ test_##name(); \ printf("ok\n"); \ tests_passed++; \ } while(0) #define ASSERT(cond) do { \ if (!(cond)) { \ printf("FAILED at line %d: %s\n", __LINE__, #cond); \ tests_failed++; \ return; \ } \ } while(0) TEST(simple_chars) { lexer_t lexer; lexer_init(&lexer, "abc"); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'b'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'c'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_EOF); } TEST(meta_chars) { lexer_t lexer; lexer_init(&lexer, ".*+?|()^$"); ASSERT(lexer_next(&lexer).type == TOKEN_DOT); ASSERT(lexer_next(&lexer).type == TOKEN_STAR); ASSERT(lexer_next(&lexer).type == TOKEN_PLUS); ASSERT(lexer_next(&lexer).type == TOKEN_QUESTION); ASSERT(lexer_next(&lexer).type == TOKEN_PIPE); ASSERT(lexer_next(&lexer).type == TOKEN_LPAREN); ASSERT(lexer_next(&lexer).type == TOKEN_RPAREN); ASSERT(lexer_next(&lexer).type == TOKEN_CARET); ASSERT(lexer_next(&lexer).type == TOKEN_DOLLAR); ASSERT(lexer_next(&lexer).type == TOKEN_EOF); } TEST(escaped_chars) { lexer_t lexer; lexer_init(&lexer, "\\*\\+\\."); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '*'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '+'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '.'); } TEST(character_classes) { lexer_t lexer; lexer_init(&lexer, "\\d\\w\\s\\D\\W\\S"); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_DIGIT); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_WORD); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_SPACE); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_NDIGIT); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_NWORD); ASSERT(lexer_next(&lexer).type == TOKEN_CLASS_NSPACE); } TEST(bracket_expression) { lexer_t lexer; lexer_init(&lexer, "[abc]"); ASSERT(lexer_next(&lexer).type == TOKEN_LBRACKET); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'b'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'c'); ASSERT(lexer_next(&lexer).type == TOKEN_RBRACKET); } TEST(bracket_range) { lexer_t lexer; lexer_init(&lexer, "[a-z]"); ASSERT(lexer_next(&lexer).type == TOKEN_LBRACKET); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); ASSERT(lexer_next(&lexer).type == TOKEN_DASH); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'z'); ASSERT(lexer_next(&lexer).type == TOKEN_RBRACKET); } TEST(negated_bracket) { lexer_t lexer; lexer_init(&lexer, "[^a]"); ASSERT(lexer_next(&lexer).type == TOKEN_LBRACKET); ASSERT(lexer_next(&lexer).type == TOKEN_CARET); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); ASSERT(lexer_next(&lexer).type == TOKEN_RBRACKET); } TEST(quantifier_braces) { lexer_t lexer; lexer_init(&lexer, "a{3}"); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); ASSERT(lexer_next(&lexer).type == TOKEN_LBRACE); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '3'); ASSERT(lexer_next(&lexer).type == TOKEN_RBRACE); } TEST(peek) { lexer_t lexer; lexer_init(&lexer, "ab"); token_t t = lexer_peek(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); t = lexer_peek(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'a'); t = lexer_peek(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == 'b'); } TEST(escape_sequences) { lexer_t lexer; lexer_init(&lexer, "\\n\\t\\r"); token_t t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '\n'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '\t'); t = lexer_next(&lexer); ASSERT(t.type == TOKEN_CHAR && t.value == '\r'); } int main(void) { printf("lexer tests:\n"); RUN_TEST(simple_chars); RUN_TEST(meta_chars); RUN_TEST(escaped_chars); RUN_TEST(character_classes); RUN_TEST(bracket_expression); RUN_TEST(bracket_range); RUN_TEST(negated_bracket); RUN_TEST(quantifier_braces); RUN_TEST(peek); RUN_TEST(escape_sequences); printf("\nlexer: %d passed, %d failed\n", tests_passed, tests_failed); return tests_failed > 0 ? 1 : 0; }