diff options
Diffstat (limited to 'src/grammar.c')
-rw-r--r-- | src/grammar.c | 150 |
1 files changed, 131 insertions, 19 deletions
diff --git a/src/grammar.c b/src/grammar.c index 1ea52b0..55a1e07 100644 --- a/src/grammar.c +++ b/src/grammar.c @@ -63,6 +63,13 @@ new_ptd(str *user_name, str *raw_name, dfa *dfap) return result; } +P_ATTR +str * +ptd_user_name(PTD *p) +{ + return p->user_name; +} + void destroy_ptd(PTD *p, int flag) { @@ -91,14 +98,8 @@ destroy_ptd_no_free(void *e) destroy_ptd((PTD *)e, 0); } -/* REVIEW: Add some statistic counts to assist the hash tables. For - example, store the total number of terminals as an integer; then - the hash table can be hinted at initialization to contain that many - elements, which can reduce the number of time a hash table needs to - expand and re-insert all its keys, which then helps the - performance. But this is not the top priority thing to do, and - might be postponed until a proto-type of the parser generator is - usable already. */ +/* FIXME: Add a list of terminals, so that we don't need to use hash + tables. */ /* rule_grps and names should have the same length */ struct Grammar_s { @@ -160,20 +161,85 @@ destroy_rule_group_free_first(void *rule_grp) static void print_sep() { - printf(", "); + printf(",\n"); } static void -print_rule_group(void *rule_grp) +print_rule_group(Grammar *g, void *rule_grp) { Rule_group *rg = (Rule_group *) rule_grp; + char s[5]; + str *strp = (str *) new_utf8(s, 5); + for (int i = 0; i < list_length(rg->rights); i++) { - List *str = (List *) list_nth(rg->rights, i); - printf("Rule %lu => ", rg->left); - map_list_between(str, print_tnt, print_sep); + /* fleprintf("i = %d\n", i); */ + List *strls = (List *) list_nth(rg->rights, i); + /* printf("Rule "); */ + for (int j = 0; + (UNUM) j < ((cpa *)list_nth(g->names, rg->left))->size; + j++) { + + if (encode + (*(((cpa *)list_nth(g->names, rg->left))->array+j), + strp)) { + destroy_str(strp, 0); + fleprintf0("Fail to encode!\n"); + return; + } + + *(s+str_length(strp)) = 0; + printf("%s", s); + str_set_length(strp, 5); + } + printf(" := "); + + for (int j = 0; j < list_length(strls); j++) { + /* fleprintf("j = %d, len = %ld\n", j, list_length(strls)); */ + TNT *tntp = (TNT *) list_nth(strls, j); + PTD *ptdp = NULL; + switch (tntp->type) { + case TERMINAL: + printf("'"); + if (encode + (tntp->data.t, + strp)) { + destroy_str(strp, 0); + fleprintf0("Fail to encode!\n"); + return; + } + printf("%s'", s); + str_set_length(strp, 5); + break; + case NONTERMINAL: + for (int k = 0; + (UNUM) k < ((cpa *)list_nth(g->names, + tntp->data.nt))->size; + k++) { + if (encode + (*(((cpa *)list_nth(g->names, tntp->data.nt))->array+k), + strp)) { + destroy_str(strp, 0); + fleprintf0("Fail to encode!\n"); + return; + } + printf("%s", s); + str_set_length(strp, 5); + } + break; + default: + /* predicate */ + ptdp = (PTD *) list_nth(g->predicates, tntp->data.pt); + /* fleprintf("pt = %lu\n", tntp->data.pt); */ + printf("[%s]", get_data(ptdp->user_name)); + break; + } + if (j+1<list_length(strls)) printf(", "); + } printf("\n"); } + + destroy_str((str*) strp, 0); } TNT * @@ -386,7 +452,7 @@ find_in_cpa_list(CCR_MOD(NUM *) string, NUM size, } void -print_name(void *element) +eprint_name(void *element) { cpa *array = (cpa *) element; char *carray = MYALLOC(char, 5); @@ -404,6 +470,32 @@ print_name(void *element) carray = get_data(string); *(carray+str_length(string)) = 0; + eprintf("%s", carray); + str_set_length(string, 5); + } + + destroy_str(string, 1); +} + +void +print_name(void *element) +{ + cpa *array = (cpa *) element; + char *carray = MYALLOC(char, 5); + str *string = new_str(carray, 5); + + for (UNUM i = 0; i < array->size; i++) { + int result = encode(*(array->array+i), string); + + if (result) { + fleprintf("%llu, fail to encode %ld\n", i, *(array->array+i)); + str_set_length(string, 5); + continue; + } + + carray = get_data(string); + *(carray+str_length(string)) = 0; + printf("%s", carray); str_set_length(string, 5); } @@ -411,8 +503,6 @@ print_name(void *element) destroy_str(string, 1); } -/* REVIEW: Print the names of non-terminals out, instead of printing - the numbers? */ void print_grammar(CC_MOD(Grammar *) g) { @@ -420,7 +510,7 @@ print_grammar(CC_MOD(Grammar *) g) printf("Non-terminals...\n"); map_list_between(g->names, print_name, print_sep); - printf("\n"); + printf("\n\n"); printf("Predicates...\n"); @@ -431,9 +521,11 @@ print_grammar(CC_MOD(Grammar *) g) get_data(ptdp->user_name), get_data(ptdp->raw_name)); } + printf("\n"); + printf("Rules...\n"); for (int i = 0; i < list_length(g->rule_grps); i++) { - print_rule_group(list_nth(g->rule_grps, i)); + print_rule_group((Grammar *) g, list_nth(g->rule_grps, i)); printf("\n"); } @@ -568,6 +660,7 @@ grammar_ptd(CCR_MOD(Grammar *) g, PT pt) return (PTD *) list_nth(g->predicates, pt); } +P_ATTR NUM grammar_left_len(CCR_MOD(Grammar *)g) { @@ -581,6 +674,13 @@ grammar_names(CCR_MOD(Grammar *)g) return g->names; } +P_ATTR +List * +grammar_preds(CCR_MOD(Grammar *)g) +{ + return g->predicates; +} + /* A transitive closure algorithm */ void epsilon_nts(CC_MOD(Grammar *) g, BOOL * const restrict nts) @@ -682,11 +782,13 @@ nt_first(CC_MOD(Grammar *) g, CCR_MOD(BOOL *) nts, BREAKOUT; } else { free(tempT); + BREAKOUT; } break; case PREDICATE: SAFE_MALLOC(NUM, tempPT, 1, return 1;); *tempPT = top->data.pt; + if (first && ht_find(predicate_hts+i, tempPT) == NULL) { changed = 1; @@ -694,6 +796,7 @@ nt_first(CC_MOD(Grammar *) g, CCR_MOD(BOOL *) nts, BREAKOUT; } else { free(tempPT); + BREAKOUT; } break; default: @@ -777,7 +880,6 @@ tnt_first(CC_MOD(ht *) terminal_hts, CC_MOD(ht *) predicate_hts, for (NUM i = 0; i < tnt_len; i++) { top = (TNT *) list_nth(tnts, i); - switch (top->type) { case TERMINAL: if (ht_find(result_terminals, &(top->data.t)) == NULL) { @@ -797,6 +899,9 @@ tnt_first(CC_MOD(ht *) terminal_hts, CC_MOD(ht *) predicate_hts, break; default: current = top->data.nt; + /* if (tnt_len == 2 && current == 1) { + * fleprintf0("generating for empty\n"); + * } */ if (current >= (NT) len || current < 0) { fleprintf("Wrong non-terminal: %ld>%ld\n", current, len); @@ -949,6 +1054,13 @@ nt_follow(CC_MOD(Grammar *) g, CCR_MOD(BOOL *) nts, for (NUM ell = 0; ell < ht_len;) { SAFE_MALLOC(NUM, tempN, 1, return 1;); *tempN = **(keys+ell++); + /* if (top->data.nt == 17 || + * top->data.nt == 14 || + * top->data.nt == 13) { + * fleprintf("add pred %ld to NT %ld\n", *tempN, + * top->data.nt); + * eprintf("i = %ld, k = %ld, ell = %ld\n", i, k, ell); + * } */ if (ht_find(result_predicates+top->data.nt, tempN) == NULL) { changed = 1; |