From 88cce7361c69636161470a84dbfb42fb723f4c07 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 2 Oct 2014 20:58:38 +1000 Subject: [PATCH] parsergen: add since_indent to stack frame. This counts frames since last indent. It is used to determine when an OUT can be canceled and when we must force a reduction. Signed-off-by: NeilBrown --- csrc/parsergen.mdc | 47 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index 45fb09e..082cf11 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -2465,6 +2465,7 @@ before the beginning. short starts_indented; short indents; short since_newline; + short since_indent; } *stack; void **asn_stack; int stack_size; @@ -2539,6 +2540,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++; @@ -2664,18 +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; - 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; @@ -2782,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) -- 2.43.0