add scaffold for grammar tests and codify the dummy test case

This commit is contained in:
Sven M. Hallberg 2013-05-08 00:48:46 +02:00
parent 188d369a9b
commit 5593b826e3
4 changed files with 96 additions and 0 deletions

View file

@ -48,6 +48,7 @@ TESTS := t_benchmark.o \
t_bitreader.o \ t_bitreader.o \
t_bitwriter.o \ t_bitwriter.o \
t_parser.o \ t_parser.o \
t_grammar.o \
test_suite.o test_suite.o
OUTPUTS := libhammer.a \ OUTPUTS := libhammer.a \

43
src/t_grammar.c Normal file
View file

@ -0,0 +1,43 @@
#include <glib.h>
#include "hammer.h"
#include "internal.h"
#include "cfgrammar.h"
#include "test_suite.h"
static void test_end(void) {
const HParser *p = h_end_p();
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
g_check_hashtable_size(g->nts, 1);
g_check_hashtable_size(g->geneps, 0);
g_check_derives_epsilon_not(g, p);
}
static void test_example_1(void) {
const HParser *c = h_many(h_ch('x'));
const HParser *q = h_sequence(c, h_ch('y'), NULL);
const HParser *p = h_choice(q, h_end_p(), NULL);
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
g_check_nonterminal(g, c);
g_check_nonterminal(g, q);
g_check_nonterminal(g, p);
g_check_derives_epsilon(g, c);
g_check_derives_epsilon_not(g, q);
g_check_derives_epsilon_not(g, p);
g_check_firstset_present(g, p, end_token);
g_check_firstset_present(g, p, char_token('x'));
g_check_firstset_present(g, p, char_token('y'));
g_check_followset_absent(g, c, end_token);
g_check_followset_absent(g, c, char_token('x'));
g_check_followset_present(g, c, char_token('y'));
}
void register_grammar_tests(void) {
g_test_add_func("/core/grammar/end", test_end);
g_test_add_func("/core/grammar/example_1", test_example_1);
}

View file

@ -22,6 +22,7 @@
extern void register_bitreader_tests(); extern void register_bitreader_tests();
extern void register_bitwriter_tests(); extern void register_bitwriter_tests();
extern void register_parser_tests(); extern void register_parser_tests();
extern void register_grammar_tests();
extern void register_benchmark_tests(); extern void register_benchmark_tests();
int main(int argc, char** argv) { int main(int argc, char** argv) {
@ -31,6 +32,7 @@ int main(int argc, char** argv) {
register_bitreader_tests(); register_bitreader_tests();
register_bitwriter_tests(); register_bitwriter_tests();
register_parser_tests(); register_parser_tests();
register_grammar_tests();
register_benchmark_tests(); register_benchmark_tests();
g_test_run(); g_test_run();

View file

@ -88,6 +88,56 @@
} \ } \
} while(0) } while(0)
#define g_check_hashtable_present(table, key) do { \
if(!h_hashtable_present(table, key)) { \
g_test_message("Check failed: key should have been in table, but wasn't"); \
g_test_fail(); \
} \
} while(0)
#define g_check_hashtable_absent(table, key) do { \
if(h_hashtable_present(table, key)) { \
g_test_message("Check failed: key shouldn't have been in table, but was"); \
g_test_fail(); \
} \
} while(0)
#define g_check_hashtable_size(table, n) do { \
size_t expected = n; \
size_t actual = (table)->used; \
if(actual != expected) { \
g_test_message("Check failed: table size should have been %lu, but was %lu", \
expected, actual); \
g_test_fail(); \
} \
} while(0)
#define g_check_terminal(grammar, parser) \
g_check_hashtable_absent(grammar->nts, h_desugar(&system_allocator, parser))
#define g_check_nonterminal(grammar, parser) \
g_check_hashtable_present(grammar->nts, h_desugar(&system_allocator, parser))
#define g_check_derives_epsilon(grammar, parser) \
g_check_hashtable_present(grammar->geneps, h_desugar(&system_allocator, parser))
#define g_check_derives_epsilon_not(grammar, parser) \
g_check_hashtable_absent(grammar->geneps, h_desugar(&system_allocator, parser))
#define g_check_firstset_present(grammar, parser, token) \
g_check_hashtable_present(h_first_symbol(grammar, h_desugar(&system_allocator, parser)), (void *)token)
#define g_check_firstset_absent(grammar, parser, token) \
g_check_hashtable_absent(h_first_symbol(grammar, h_desugar(&system_allocator, parser)), (void *)token)
#define g_check_followset_present(grammar, parser, token) \
g_check_hashtable_present(h_follow(grammar, h_desugar(&system_allocator, parser)), (void *)token)
#define g_check_followset_absent(grammar, parser, token) \
g_check_hashtable_absent(h_follow(grammar, h_desugar(&system_allocator, parser)), (void *)token)
#define g_check_cmpint(n1, op, n2) g_check_inttype("%d", int, n1, op, n2) #define g_check_cmpint(n1, op, n2) g_check_inttype("%d", int, n1, op, n2)
#define g_check_cmplong(n1, op, n2) g_check_inttype("%ld", long, n1, op, n2) #define g_check_cmplong(n1, op, n2) g_check_inttype("%ld", long, n1, op, n2)