]> ocean-lang.org Git - ocean/commitdiff
parsergen: don't use static buffer for result value.
authorNeilBrown <neil@brown.name>
Fri, 26 Feb 2021 06:33:43 +0000 (17:33 +1100)
committerNeilBrown <neil@brown.name>
Wed, 10 Mar 2021 01:00:31 +0000 (12:00 +1100)
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 <neil@brown.name>
csrc/parsergen.mdc

index 5d2e164221fb38488948210128bf007390f0e561..a140e37f8c000eac4cb94278d1528c309da88e2b 100644 (file)
@@ -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 <memory.h>
 
 ###### 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)) {