#include #include #include #include "../grammar.h" #define GET_KEY(T, K, N) *((T*)*(K+N)) #define READ_INTO_CPA(N, U, I, VA, VI, CP) do { \ U = new_utf8(N, 1); \ I = get_info((str *)U, 0); \ VA = MYALLOC(NUM, 1); \ VI = 0; \ for (NUM index = 0; \ I.value >= 0 && index < str_length((str *) U); \ index += I.step, VI++) { \ I = get_info((str *)U, index); \ *(VA+VI) = I.value; \ } \ CP = MYALLOC(cpa, 1); \ CP->array = VA; \ CP->size = VI; \ add_to_list(names, CP); \ destroy_str((str *)U, 1); \ } while (0) #define READ_TNT_STRING(LEFT, FORMAT, LEN, ...) do { \ tnt_string = new_tnt_string(FORMAT, LEN, __VA_ARGS__); \ if (!tnt_string) { \ fleprintf("left = %d, f = %s, l = %d, " \ "cannot create tnt string\n", \ LEFT, FORMAT, LEN); \ map_list(rules, destroy_rule_and_free_all); \ destroy_list(rules, 0); \ map_list(names, destroy_cpa_and_free_all); \ destroy_list(names, 0); \ return 1; \ } \ rule = new_rule(LEFT, tnt_string); \ add_to_list(rules, rule); \ } while (0) static void print_sep() { printf(", "); } int main(UNUSED int argc, UNUSED char **argv) { /* check new_tnt and print it */ TNT *tnt = new_tnt(NONTERMINAL, 12); printf("Print a TNT value of type NT: "); print_tnt(tnt); printf("\n"); free(tnt); /* check new_tnt_string */ List *tnt_string = new_tnt_string("tntnt", 5, (T) 1, (NT) 2, (T) 3, (NT) 4, (T) 15); if (!tnt_string) { eprintf("error!\n"); return 1; } /* check new_rule, print_rule, and destroy_rule. */ Rule *rule = new_rule(1, tnt_string); print_rule(rule); destroy_rule(rule, 1); /* check build_grammar, print_grammar, and destroy_grammar */ List *rules = new_list(); List *names = new_list(); char *name = MYALLOC(char, 2); *(name+1) = 0; *name = 'E'; utf8* uname = NULL; str_info info = EMPTY_STR_INFO; NUM *varray = NULL; NUM vindex = 0; cpa *cpap = NULL; READ_INTO_CPA(name, uname, info, varray, vindex, cpap); name = MYALLOC(char, 2); *(name+1) = 0; *name = 'T'; READ_INTO_CPA(name, uname, info, varray, vindex, cpap); name = MYALLOC(char, 2); *(name+1) = 0; *name = 'F'; READ_INTO_CPA(name, uname, info, varray, vindex, cpap); name = MYALLOC(char, 2); *(name+1) = 0; *name = 'D'; READ_INTO_CPA(name, uname, info, varray, vindex, cpap); READ_TNT_STRING(0, "n", 1, (NT) 1); READ_TNT_STRING(0, "ntn", 3, (NT) 1, (T) 43, (NT) 1); READ_TNT_STRING(1, "n", 1, (NT) 2); READ_TNT_STRING(1, "ntn", 3, (NT) 2, (T) 42, (NT) 2); READ_TNT_STRING(2, "n", 1, (NT) 3); READ_TNT_STRING(2, "tnt", 3, (T) 40, (NT) 0, (T) 41); READ_TNT_STRING(3, "tn", 1, (T) 48, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 49, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 50, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 51, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 52, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 53, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 54, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 55, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 56, (NT) 3); READ_TNT_STRING(3, "tn", 1, (T) 57, (NT) 3); rule = new_rule(3, new_list()); add_to_list(rules, rule); Grammar *g = new_grammar(); build_grammar(g, rules, names); print_grammar(g); Rule_group *rg = grammar_rule(g, 0); List *tnts = list_nth((List *) rg_right(rg), 1); map_list(tnts, print_tnt); printf("\n"); printf("\n\n"); /* TODO: Check first and follow sets */ NUM left_len = grammar_left_len(g); BOOL *epsilon_array = NULL; ht *terminal_hts = NULL, *predicate_hts = NULL; ht *test_terminal_hts = NULL, *test_predicate_hts = NULL; ht *result_terminal_hts = NULL, *result_predicate_hts = NULL; ht *tnt_ht = NULL; List *test_tnt_string = NULL; SAFE_MALLOC(BOOL, epsilon_array, left_len, goto cleanup;); epsilon_nts(g, epsilon_array); printf("Printing the epsilon array...\n"); for (NUM i = 0; i < left_len;) { if (*(epsilon_array+i)) printf("ε"); else printf(" "); if (++i