]> ocean-lang.org Git - ocean/blobdiff - csrc/parsergen.mdc
parsergen: remove starts_indented.
[ocean] / csrc / parsergen.mdc
index 45fb09e5228f26ce3240a8daa46f1d6d092ffa7d..f99d318482d9f1b3568515a3c2d4440dc75b94aa 100644 (file)
@@ -2437,9 +2437,8 @@ The `state` is the most important one and guides the parsing process.  The
 freeing function.  The symbol leads us to the right free function through
 `do_free`.
 
-The `indents` count and the `starts_indented` flag track the line
-indents in the symbol.  These are used to allow indent information to
-guide parsing and error recovery.
+The `indents` count tracks the line indents in the symbol.  These are
+used to allow indent information to guide parsing and error recovery.
 
 `since_newline` tracks how many stack frames since the last
 start-of-line (whether indented or not).  So if `since_newline` is
@@ -2462,9 +2461,9 @@ before the beginning.
                        short newline_permitted;
 
                        short sym;
-                       short starts_indented;
                        short indents;
                        short since_newline;
+                       short since_indent;
                } *stack;
                void **asn_stack;
                int stack_size;
@@ -2539,6 +2538,13 @@ So we walk down:
                        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++;
@@ -2560,8 +2566,6 @@ removed. It is called _after_ we reduce a production, just before we
        {
                int i;
                p->tos -= num;
-               next->starts_indented =
-                       p->stack[p->tos].starts_indented;
                next->since_newline =
                        p->stack[p->tos].since_newline;
                next->indents = 0;
@@ -2655,7 +2659,6 @@ since the last state which could have been at the start of a line.
                        parser_trace(trace, &p, &next, tk, states, non_term, config->known_count);
 
                        if (next.sym == TK_in) {
-                               next.starts_indented = 1;
                                next.indents = 1;
                                next.since_newline = 0;
                                free(tk);
@@ -2664,18 +2667,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;
-                                               else
-                                                       tos->newline_permitted = 0;
+                               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;
@@ -2698,7 +2715,6 @@ since the last state which could have been at the start of a line.
                        }
                        if (shift(&p, &next, tk, states)) {
                                next.since_newline = !(tk->num == TK_newline);
-                               next.starts_indented = 0;
                                next.indents = 0;
                                tk = NULL;
                                parser_trace_action(trace, "Shift");
@@ -2724,10 +2740,8 @@ since the last state which could have been at the start of a line.
                                        pop(&p, size, &frame, do_free);
                                else {
                                        frame.indents = next.indents;
-                                       frame.starts_indented = frame.indents;
                                        frame.since_newline = 1;
                                        next.indents = 0;
-                                       next.starts_indented = 0;
                                }
                                res = memdup(buf, bufsize);
                                memset(buf, 0, bufsize);
@@ -2782,6 +2796,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)
@@ -2860,8 +2875,7 @@ end inside square brackets.
                                        fputs(non_term[sym - TK_reserved - knowns],
                                              trace);
                                if (f->indents)
-                                       fprintf(trace, "%c%d", f->starts_indented?':':'.',
-                                               f->indents);
+                                       fprintf(trace, ".%d", f->indents);
                                if (f->since_newline == 0)
                                        fputs("/", trace);
                                fputs(" ", trace);
@@ -2875,8 +2889,7 @@ end inside square brackets.
                else
                        text_dump(trace, tk->txt, 20);
                if (n->indents)
-                       fprintf(trace, "%c%d", n->starts_indented?':':'.',
-                               n->indents);
+                       fprintf(trace, ".%d", n->indents);
                if (n->since_newline == 0)
                        fputs("/", trace);
                fputs("]", trace);