]> ocean-lang.org Git - ocean/blobdiff - csrc/parsergen.mdc
parsegen: unify the "next" frame to go onto stack.
[ocean] / 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);