We current have a current 'state' in the parser and a 'sym'
which is a local variable passed around in different ways.
Both of these get pushed onto the stack at the next 'shift'.
We will shortly add some more fields to the stack frame, so unify
'state' and 'sym' in to a 'next' struct in the parser struct which can
easily be extended.
Signed-off-by: NeilBrown <neilb@suse.de>
freeing function. The symbol leads us to the right free function through
`do_free`.
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 {
###### parser functions
struct parser {
struct frame {
short state;
short sym;
struct frame {
short state;
short sym;
void **asn_stack;
int stack_size;
int tos;
void **asn_stack;
int stack_size;
int tos;
###### parser functions
static int shift(struct parser *p,
###### parser functions
static int shift(struct parser *p,
const struct state states[])
{
// Push an entry onto the stack
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) {
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->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->asn_stack[p->tos] = asn;
p->tos++;
+ p->next.state = newstate;
do_free(p->stack[p->tos+i].sym,
p->asn_stack[p->tos+i]);
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;
tk = tok_copy(token_next(tokens));
while (!accepted) {
tk = tok_copy(token_next(tokens));
while (!accepted) {
if (trace)
parser_trace(trace, &p, tk, states, non_term, knowns);
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;
}
tk = tok_copy(token_next(tokens));
continue;
}
- if (states[p.state].reduce_prod >= 0) {
+ if (states[p.next.state].reduce_prod >= 0) {
- 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];
int bufsize;
static char buf[16*1024];
+ p.next.sym = states[p.next.state].reduce_sym;
- (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);
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;
if (prod == 0)
accepted = 1;
continue;
* Then we discard input tokens until
* we find one that is acceptable.
*/
* 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);
&& 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));
tk->num != TK_eof) {
free(tk);
tk = tok_copy(token_next(tokens));
trace);
fputs(" ", trace);
}
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);
if (tk->num < TK_reserved &&
reserved_words[tk->num] != NULL)
fputs(reserved_words[tk->num], trace);