add scaffold for grammar tests and codify the dummy test case
This commit is contained in:
parent
188d369a9b
commit
5593b826e3
4 changed files with 96 additions and 0 deletions
|
|
@ -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
43
src/t_grammar.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue