]> ocean-lang.org Git - ocean/commitdiff
parsegen: unify the "next" frame to go onto stack.
authorNeilBrown <neilb@suse.de>
Sun, 24 Nov 2013 06:36:41 +0000 (17:36 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 24 Nov 2013 06:36:41 +0000 (17:36 +1100)
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>
csrc/parsergen.mdc

index 7b6664d9cb250125a1f508e9c99402e9e49542cd..ec9b8f263f624de44b76419d4e4ab68d3a7576b4 100644 (file)
@@ -2251,14 +2251,17 @@ 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`.
 
+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;
@@ -2285,11 +2288,11 @@ if needed and pushed all the information onto the stacks.
 ###### 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) {
@@ -2299,11 +2302,10 @@ if needed and pushed all the information onto the stacks.
                        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;
        }
 
@@ -2322,7 +2324,8 @@ reduce a production, just before we `shift` the nonterminal in.
                        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
@@ -2383,28 +2386,29 @@ drop input tokens until we find one we can shift into the new error state.
 
                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;
@@ -2416,12 +2420,13 @@ drop input tokens until we find one we can shift into the new error state.
                         * 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));
@@ -2491,7 +2496,7 @@ end inside square brackets.
                                      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);