|
/* retoor <retoor@molodetz.nl> */
|
|
#include "../include/nfa.h"
|
|
#include "../include/parser.h"
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
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)
|
|
|
|
static nfa_t *compile_pattern(const char *pattern) {
|
|
parser_t parser;
|
|
parser_init(&parser, pattern);
|
|
ast_node_t *ast = parser_parse(&parser);
|
|
if (!ast || parser_get_error(&parser) != LOREX_OK) {
|
|
ast_free(ast);
|
|
return NULL;
|
|
}
|
|
lorex_error_t error;
|
|
nfa_t *nfa = nfa_from_ast(ast, &error);
|
|
ast_free(ast);
|
|
return nfa;
|
|
}
|
|
|
|
TEST(single_char) {
|
|
nfa_t *nfa = compile_pattern("a");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
ASSERT(nfa->state_count >= 2);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(concat) {
|
|
nfa_t *nfa = compile_pattern("ab");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(alternation) {
|
|
nfa_t *nfa = compile_pattern("a|b");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(star) {
|
|
nfa_t *nfa = compile_pattern("a*");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(plus) {
|
|
nfa_t *nfa = compile_pattern("a+");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(question) {
|
|
nfa_t *nfa = compile_pattern("a?");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(group) {
|
|
nfa_t *nfa = compile_pattern("(ab)");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->group_count == 1);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(nested_groups) {
|
|
nfa_t *nfa = compile_pattern("((a)(b))");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->group_count == 3);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(bracket) {
|
|
nfa_t *nfa = compile_pattern("[abc]");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(quantifier) {
|
|
nfa_t *nfa = compile_pattern("a{2,4}");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(complex_pattern) {
|
|
nfa_t *nfa = compile_pattern("^([a-z]+)@([a-z]+)\\.([a-z]{2,})$");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->group_count == 3);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(dot) {
|
|
nfa_t *nfa = compile_pattern("a.b");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(anchors) {
|
|
nfa_t *nfa = compile_pattern("^abc$");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
TEST(character_classes) {
|
|
nfa_t *nfa = compile_pattern("\\d\\w\\s");
|
|
ASSERT(nfa != NULL);
|
|
ASSERT(nfa->start != NULL);
|
|
nfa_free(nfa);
|
|
}
|
|
|
|
int main(void) {
|
|
printf("nfa tests:\n");
|
|
|
|
RUN_TEST(single_char);
|
|
RUN_TEST(concat);
|
|
RUN_TEST(alternation);
|
|
RUN_TEST(star);
|
|
RUN_TEST(plus);
|
|
RUN_TEST(question);
|
|
RUN_TEST(group);
|
|
RUN_TEST(nested_groups);
|
|
RUN_TEST(bracket);
|
|
RUN_TEST(quantifier);
|
|
RUN_TEST(complex_pattern);
|
|
RUN_TEST(dot);
|
|
RUN_TEST(anchors);
|
|
RUN_TEST(character_classes);
|
|
|
|
printf("\nnfa: %d passed, %d failed\n", tests_passed, tests_failed);
|
|
return tests_failed > 0 ? 1 : 0;
|
|
}
|