freeing function. The symbol leads us to the right free function through
`do_free`.
+As well as the stack of frames we have a `next` frame which is
+assembled from the incoming token and other information prior to
+pushing it onto the stack.
+
###### parser functions
struct parser {
- int state;
struct frame {
short state;
short sym;
- } *stack;
+ } *stack, next;
void **asn_stack;
int stack_size;
int tos;
###### parser functions
static int shift(struct parser *p,
- int sym, void *asn,
+ void *asn,
const struct state states[])
{
// Push an entry onto the stack
- int newstate = search(&states[p->state], sym);
+ int newstate = search(&states[p->next.state], p->next.sym);
if (newstate < 0)
return 0;
if (p->tos >= p->stack_size) {
p->asn_stack = realloc(p->asn_stack, p->stack_size
* sizeof(p->asn_stack[0]));
}
- p->stack[p->tos].state = p->state;
- p->stack[p->tos].sym = sym;
+ p->stack[p->tos] = p->next;
p->asn_stack[p->tos] = asn;
p->tos++;
- p->state = newstate;
+ p->next.state = newstate;
return 1;
}
do_free(p->stack[p->tos+i].sym,
p->asn_stack[p->tos+i]);
- p->state = p->stack[p->tos].state;
+ if (num)
+ p->next.state = p->stack[p->tos].state;
}
### Memory allocation
tk = tok_copy(token_next(tokens));
while (!accepted) {
+ p.next.sym = tk->num;
if (trace)
parser_trace(trace, &p, tk, states, non_term, knowns);
- if (shift(&p, tk->num, tk, states)) {
+ if (shift(&p, tk, states)) {
tk = tok_copy(token_next(tokens));
continue;
}
- if (states[p.state].reduce_prod >= 0) {
+ if (states[p.next.state].reduce_prod >= 0) {
void **body;
- int prod = states[p.state].reduce_prod;
- int size = states[p.state].reduce_size;
- int sym = states[p.state].reduce_sym;
+ int prod = states[p.next.state].reduce_prod;
+ int size = states[p.next.state].reduce_size;
int bufsize;
static char buf[16*1024];
+ p.next.sym = states[p.next.state].reduce_sym;
body = p.asn_stack +
- (p.tos - states[p.state].reduce_size);
+ (p.tos - states[p.next.state].reduce_size);
bufsize = do_reduce(prod, body, buf);
pop(&p, size, do_free);
- shift(&p, sym, memdup(buf, bufsize), states);
+ shift(&p, memdup(buf, bufsize), states);
if (prod == 0)
accepted = 1;
continue;
* Then we discard input tokens until
* we find one that is acceptable.
*/
- while (shift(&p, TK_error, tk, states) == 0
+ p.next.sym = TK_error;
+ while (shift(&p, tk, states) == 0
&& p.tos > 0)
// discard this state
pop(&p, 1, do_free);
tk = tok_copy(*tk);
- while (search(&states[p.state], tk->num) < 0 &&
+ while (search(&states[p.next.state], tk->num) < 0 &&
tk->num != TK_eof) {
free(tk);
tk = tok_copy(token_next(tokens));
trace);
fputs(" ", trace);
}
- fprintf(trace, "(%d) [", p->state);
+ fprintf(trace, "(%d) [", p->next.state);
if (tk->num < TK_reserved &&
reserved_words[tk->num] != NULL)
fputs(reserved_words[tk->num], trace);