]> ocean-lang.org Git - ocean/blobdiff - csrc/parsergen.mdc
parsergen: add since_indent to stack frame.
[ocean] / csrc / parsergen.mdc
index 7859a983222d52a106386be55c127efa6e96d952..082cf117cb1abf8e2e3d50fcc89c6a806502ee71 100644 (file)
@@ -1178,6 +1178,7 @@ should happen, so we don't need to search a second time.
                struct symset go_to;
                char completed;
                char starts_line;
+               int min_prefix;
        };
 
 ###### grammar fields
@@ -1284,6 +1285,9 @@ though.
                struct symset LA = INIT_SYMSET;
                unsigned short sn = 0;
 
+               if (is->min_prefix == 0 ||
+                   (bs > 0 && bs < is->min_prefix))
+                       is->min_prefix = bs;
                if (bs == pr->body_size)
                        continue;
                s = pr->body[bs];
@@ -1629,7 +1633,8 @@ Now we can report all the item sets complete with items, LA sets, and GO TO.
                for (s = 0; s < g->states; s++) {
                        int j;
                        struct itemset *is = g->statetab[s];
-                       printf("  Itemset %d:%s\n", s, is->starts_line?" (startsline)":"");
+                       printf("  Itemset %d:%s min prefix=%d\n",
+                              s, is->starts_line?" (startsline)":"", is->min_prefix);
                        for (j = 0; j < is->items.cnt; j++) {
                                report_item(g, is->items.syms[j]);
                                if (is->items.data != NO_DATA)
@@ -1893,6 +1898,7 @@ The go to table is stored in a simple array of `sym` and corresponding
                short reduce_sym;
                short shift_sym;
                short starts_line;
+               short min_prefix;
        };
 
 
@@ -1949,15 +1955,15 @@ The go to table is stored in a simple array of `sym` and corresponding
                        }
 
                        if (prod >= 0)
-                               fprintf(f, "\t[%d] = { %d, goto_%d, %d, %d, %d, 0, %d },\n",
+                               fprintf(f, "\t[%d] = { %d, goto_%d, %d, %d, %d, 0, %d, %d },\n",
                                        i, is->go_to.cnt, i, prod,
                                        g->productions[prod]->body_size,
                                        g->productions[prod]->head->num,
-                                       is->starts_line);
+                                       is->starts_line, is->min_prefix);
                        else
-                               fprintf(f, "\t[%d] = { %d, goto_%d, -1, -1, -1, %d, %d },\n",
+                               fprintf(f, "\t[%d] = { %d, goto_%d, -1, -1, -1, %d, %d, %d },\n",
                                        i, is->go_to.cnt, i, shift_sym,
-                                       is->starts_line);
+                                       is->starts_line, is->min_prefix);
                }
                fprintf(f, "};\n\n");
        }
@@ -2459,6 +2465,7 @@ before the beginning.
                        short starts_indented;
                        short indents;
                        short since_newline;
+                       short since_indent;
                } *stack;
                void **asn_stack;
                int stack_size;
@@ -2517,22 +2524,29 @@ So we walk down:
                                           * sizeof(p->asn_stack[0]));
                }
                next->state = newstate;
-               next->newline_permitted = 0;
-               if (p->tos)
-                       next->newline_permitted =
-                               (p->stack[p->tos-1].newline_permitted?:-1)+1;
-               if (next->indents > next->starts_indented)
-                       next->newline_permitted = 0;
-               if (next->indents && next->newline_permitted > 2)
-                       next->newline_permitted = 0;
                if (states[newstate].starts_line)
                        next->newline_permitted = 1;
+               else if (next->indents)
+                       next->newline_permitted = 0;
+               else if (p->tos)
+                       next->newline_permitted =
+                               p->stack[p->tos-1].newline_permitted;
+               else
+                       next->newline_permitted = 0;
+
                if (next->since_newline) {
                        if (p->tos)
                                next->since_newline = p->stack[p->tos-1].since_newline + 1;
                        else
                                next->since_newline = 1;
                }
+               if (next->indents)
+                       next->since_indent = 0;
+               else if (p->tos)
+                       next->since_indent = p->stack[p->tos-1].since_indent + 1;
+               else
+                       next->since_indent = 1;
+
                p->stack[p->tos] = *next;
                p->asn_stack[p->tos] = asn;
                p->tos++;
@@ -2658,16 +2672,32 @@ since the last state which could have been at the start of a line.
                                continue;
                        }
                        if (next.sym == TK_out) {
-                               if (tos->indents > tos->starts_indented ||
-                                   (tos->indents == 1 &&
-                                    states[tos->state].reduce_size != 1)) {
-                                       tos->indents -= 1;
-                                       if (tos->indents <= tos->starts_indented) {
-                                               // no internal indent any more, reassess 'newline_permitted'
-                                               if (states[tos->state].starts_line)
-                                                       tos->newline_permitted = 1;
-                                               else if (p.tos > 1)
-                                                       tos->newline_permitted = (p.stack[p.tos-2].newline_permitted ?:-1)+1;
+                               if (states[tos->state].reduce_size >= 0 &&
+                                   states[tos->state].reduce_size <= tos->since_indent)
+                                       goto force_reduce;
+                               if (states[tos->state].min_prefix >= tos->since_indent) {
+                                       // OK to cancel
+                                       struct frame *in = tos - tos->since_indent;
+                                       in->indents -= 1;
+                                       if (in->indents == 0) {
+                                               /* Reassess since_indent and newline_permitted */
+                                               if (in > p.stack) {
+                                                       in->since_indent = in[-1].since_indent + 1;
+                                                       in->newline_permitted = in[-1].newline_permitted;
+                                               } else {
+                                                       in->since_indent = 0;
+                                                       in->newline_permitted = 0;
+                                               }
+                                               if (states[in->state].starts_line)
+                                                       in->newline_permitted = 0;
+                                               while (in < tos) {
+                                                       in += 1;
+                                                       in->since_indent = in[-1].since_indent + 1;
+                                                       if (states[in->state].starts_line)
+                                                               in->newline_permitted = 1;
+                                                       else
+                                                               in->newline_permitted = in[-1].newline_permitted;
+                                               }
                                        }
                                        free(tk);
                                        tk = NULL;
@@ -2678,7 +2708,7 @@ since the last state which could have been at the start of a line.
                                // will fail).
                        }
                        if (next.sym == TK_newline) {
-                               if (! tos->newline_permitted) {
+                               if (!tos->newline_permitted) {
                                        free(tk);
                                        tk = NULL;
                                        parser_trace_action(trace, "Discard");
@@ -2774,6 +2804,7 @@ since the last state which could have been at the start of a line.
                                        if (next.indents == 0)
                                                break;
                                        next.indents -= 1;
+                                       // FIXME update since_indent here
                                }
                        }
                        if (p.tos == 0 && tk->num == TK_eof)