short sym;
short starts_indented;
short indents;
- short starts_newline;
+ short since_newline;
} *stack;
void **asn_stack;
int stack_size;
next->newline_permitted = 0;
if (states[newstate].starts_line)
next->newline_permitted = 1;
+ if (next->since_newline) {
+ if (p->tos)
+ next->since_newline = p->stack[p->tos-1].since_newline + 1;
+ else
+ next->since_newline = 1;
+ }
p->stack[p->tos] = *next;
p->asn_stack[p->tos] = asn;
p->tos++;
p->tos -= num;
next->starts_indented =
p->stack[p->tos].starts_indented;
- next->starts_newline =
- p->stack[p->tos].starts_newline;
+ next->since_newline =
+ p->stack[p->tos].since_newline;
next->indents = 0;
for (i = 0; i < num; i++) {
next->indents += p->stack[p->tos+i].indents;
int accepted = 0;
void *ret = NULL;
- next.starts_newline = 1;
shift(&p, &next, NULL, states);
while (!accepted) {
struct token *err_tk;
if (next.sym == TK_in) {
next.starts_indented = 1;
next.indents = 1;
- next.starts_newline = 1;
+ next.since_newline = 0;
free(tk);
tk = NULL;
parser_trace_action(trace, "Record");
parser_trace_action(trace, "Discard");
continue;
}
+ if (states[tos->state].reduce_size > 0 &&
+ states[tos->state].reduce_size < tos->since_newline)
+ goto force_reduce;
}
if (shift(&p, &next, tk, states)) {
- next.starts_newline =
- tk->num == TK_newline;
+ next.since_newline = !(tk->num == TK_newline);
next.starts_indented = 0;
next.indents = 0;
tk = NULL;
parser_trace_action(trace, "Shift");
continue;
}
+ force_reduce:
if (states[tos->state].reduce_prod >= 0) {
void **body;
void *res;
else {
frame.indents = next.indents;
frame.starts_indented = frame.indents;
- frame.starts_newline = 0;
+ frame.since_newline = 1;
next.indents = 0;
next.starts_indented = 0;
}
struct frame frame = { 0 };
fprintf(stderr, "Synthesize %d to handle indent problem\n", states[tos->state].shift_sym);
frame.sym = states[tos->state].shift_sym;
+ frame.since_newline = 1;
shift(&p, &frame, tok_copy(*tk), states);
// FIXME need to report this error somehow
parser_trace_action(trace, "Synthesize");
if (f->indents)
fprintf(trace, "%c%d", f->starts_indented?':':'.',
f->indents);
- if (f->starts_newline)
+ if (f->since_newline == 0)
fputs("/", trace);
fputs(" ", trace);
}
if (n->indents)
fprintf(trace, "%c%d", n->starts_indented?':':'.',
n->indents);
- if (n->starts_newline)
+ if (n->since_newline == 0)
fputs("/", trace);
fputs("]", trace);
}