From: NeilBrown Date: Fri, 26 Feb 2021 06:33:43 +0000 (+1100) Subject: parsergen: don't use static buffer for result value. X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=0b4b292a5e6744bcf7f35e012466c969c115c1b5 parsergen: don't use static buffer for result value. Add the size of the result value to the per-state information, so it can be allocated before calling do_reduce(), thus removing the need for a overly large static buffer. Signed-off-by: NeilBrown --- diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index 5d2e164..a140e37 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -2056,6 +2056,7 @@ The go to table is stored in a simple array of `sym` and corresponding char starts_line; char newline_only; short min_prefix; + short result_size; }; ###### functions @@ -2109,14 +2110,22 @@ The go to table is stored in a simple array of `sym` and corresponding fprintf(f, "\t[%d] = { 0, NULL, ", i); if (prod >= 0) { struct production *pr = g->productions[prod]; - fprintf(f, "%d, %d, %d, %d, %d, %d },\n", prod, + struct symbol *hd = pr->head; + fprintf(f, "%d, %d, %d, %d, %d, %d, ", prod, pr->body_size, pr->head->num, is->starts_line, pr->line_like, is->min_prefix); + if (hd->struct_name.txt == NULL) + fprintf(f, "0 },\n"); + else + fprintf(f, "sizeof(struct %.*s%s) },\n", + hd->struct_name.len, + hd->struct_name.txt, + hd->isref ? "*" : ""); } else - fprintf(f, "-1, -1, -1, %d, 0, %d },\n", + fprintf(f, "-1, -1, -1, %d, 0, %d, -1 },\n", is->starts_line, is->min_prefix); } fprintf(f, "};\n\n"); @@ -2674,25 +2683,14 @@ table. ### 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`. +memory so they can live in the `asn_stack`. So we provide `tok_copy` to +make an allocated copy as required. ###### 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)); @@ -3060,18 +3058,18 @@ checks if a given token is in any of these look-ahead sets. const struct state *nextstate = &states[tos->state]; int prod = nextstate->reduce_prod; int size = nextstate->reduce_size; - int bufsize; - static char buf[16*1024]; + int res_size = nextstate->result_size; short indents, start_of_line; body = p.asn_stack + (p.tos - size); - - bufsize = do_reduce(prod, body, config, buf); + res = res_size ? calloc(1, res_size) : NULL; + res_size = do_reduce(prod, body, config, res); + if (res_size != nextstate->result_size) + abort(); indents = pop(&p, size, &start_of_line, do_free); - res = memdup(buf, bufsize); - memset(buf, 0, bufsize); + if (!shift(&p, nextstate->reduce_sym, indents, start_of_line, res, states)) {