X-Git-Url: https://ocean-lang.org/code/?a=blobdiff_plain;f=csrc%2Fparsergen.mdc;h=9156c63041121d0ef1f0e34bc7b45932967128b8;hb=795dc527884643585eefc9bfe2d3a5f4b2ad7376;hp=e0a2167ef1eecf41936c4762d8935bd464190e86;hpb=663f971dfab3f07a5153139cc7ca80c373dedd63;p=ocean diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index e0a2167..9156c63 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -561,6 +561,7 @@ Now we have all the bits we need to parse a full production. abort: while (tk.num != TK_newline && tk.num != TK_eof) tk = token_next(state); + free(p.body); return err; } @@ -695,7 +696,7 @@ used as a terminal anywhere that a terminal is expected. s->name.len, s->name.txt); } if (errs) { - free(g); + free(g); // FIXME free content g = NULL; } } @@ -704,7 +705,7 @@ used as a terminal anywhere that a terminal is expected. fprintf(stderr, "Error at line %d: %s\n", tk.line, err); token_close(state); - free(g); + free(g); // FIXME free content return NULL; } @@ -1071,6 +1072,9 @@ and we find the set of possible "first" symbols after there. This is done using `add_first` above and only needs to be done once as the "first" sets are now stable and will not change. +###### grammar fields + struct symset *follow; + ###### follow code for (p = 0; p < g->production_count; p++) { @@ -1097,10 +1101,10 @@ combine these two functions into a single loop. ###### follow code - for (again = 0, p = 0; + for (check_again = 0, p = 0; p < g->production_count; p < g->production_count-1 - ? p++ : again ? (again = 0, p = 0) + ? p++ : check_again ? (check_again = 0, p = 0) : p++) { struct production *pr = g->productions[p]; int b; @@ -1111,7 +1115,7 @@ combine these two functions into a single loop. break; if (symset_union(&g->follow[bs->num], &g->follow[pr->head->num])) - again = 1; + check_again = 1; if (!bs->nullable) break; } @@ -1120,13 +1124,10 @@ combine these two functions into a single loop. We now just need to create and initialise the `follow` list to get a complete function. -###### grammar fields - struct symset *follow; - ###### functions static void build_follow(struct grammar *g) { - int s, again, p; + int s, check_again, p; g->follow = calloc(g->num_syms, sizeof(g->follow[0])); for (s = 0; s < g->num_syms; s++) g->follow[s] = INIT_SYMSET; @@ -1407,7 +1408,7 @@ so the item is ineffective. continue; if (s->line_like) is->starts_line = 1; - again = 1; + check_again = 1; if (type >= LALR) { // Need the LA set. int to_end; @@ -1527,7 +1528,7 @@ with `TK_eof` as the LA set. { struct symset first = INIT_SYMSET; struct itemset *is; - int again; + int check_again; unsigned short la = 0; if (type >= LALR) { // LA set just has eof @@ -1539,15 +1540,15 @@ with `TK_eof` as the LA set. // production 0, offset 0 (with no data) symset_add(&first, item_num(0, 0), la); add_itemset(g, first, Non, 0, type); - for (again = 0, is = g->items; + for (check_again = 0, is = g->items; is; - is = is->next ?: again ? (again = 0, g->items) : NULL) { + is = is->next ?: check_again ? (check_again = 0, g->items) : NULL) { int i; struct symset done = INIT_SYMSET; if (is->completed) continue; is->completed = 1; - again = 1; + check_again = 1; ## complete itemset ## derive itemsets symset_free(done); @@ -2072,8 +2073,6 @@ The go to table is stored in a simple array of `sym` and corresponding } } -###### functions - static void gen_states(FILE *f, struct grammar *g) { int i; @@ -2661,6 +2660,35 @@ table. return -1; } +### Memory allocation + +The `scanner` returns tokens in a local variable - we want them in allocated +memory so they can live in the `asn_stack`. Similarly the `asn` produced by +a reduce is in a large buffer. Both of these require some allocation and +copying, hence `memdup` and `tok_copy`. + +###### parser includes + #include + +###### parser functions + + void *memdup(void *m, int len) + { + void *ret; + if (len == 0) + return NULL; + ret = malloc(len); + memcpy(ret, m, len); + return ret; + } + + static struct token *tok_copy(struct token tk) + { + struct token *new = malloc(sizeof(*new)); + *new = tk; + return new; + } + ### The state stack. The core data structure for the parser is the stack. This tracks all @@ -2833,35 +2861,6 @@ before we `shift` the nonterminal in. return indents; } -### Memory allocation - -The `scanner` returns tokens in a local variable - we want them in allocated -memory so they can live in the `asn_stack`. Similarly the `asn` produced by -a reduce is in a large buffer. Both of these require some allocation and -copying, hence `memdup` and `tokcopy`. - -###### parser includes - #include - -###### parser functions - - void *memdup(void *m, int len) - { - void *ret; - if (len == 0) - return NULL; - ret = malloc(len); - memcpy(ret, m, len); - return ret; - } - - static struct token *tok_copy(struct token tk) - { - struct token *new = malloc(sizeof(*new)); - *new = tk; - return new; - } - ### The heart of the parser. Now we have the parser. For each token we might shift it, trigger a