]> ocean-lang.org Git - ocean/commitdiff
parsergen: pass 'config' in to 'reduce' function.
authorNeilBrown <neil@brown.name>
Sat, 31 May 2014 05:56:20 +0000 (15:56 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 15 Jun 2014 07:20:30 +0000 (17:20 +1000)
As we only support synthesise attributes and no inherited attributes,
we have no way for the reduce functions to access any context (such
as building a table of variables) except via global variables (yuck).

So pass the 'context' pointer through.  The main program can embed
this in a larger structure which contains relevant context, and
the reduce functions can find that using pointer manipulation.

Signed-off-by: NeilBrown <neil@brown.name>
csrc/parsergen.mdc

index f87e961d806672fee891677254282767d69673d1..8e088b5b70c5150671f0afbbf84933739c073ef6 100644 (file)
@@ -1802,7 +1802,7 @@ pieces of code provided in the grammar file, so they are generated first.
                fprintf(f, "\tconfig->known_count = sizeof(known)/sizeof(known[0]);\n");
                fprintf(f, "\tconfig->ignored |= (1 << TK_line_comment) | (1 << TK_block_comment);\n");
                fprintf(f, "\ttokens = token_open(code, config);\n");
-               fprintf(f, "\tvoid *rv = parser_run(tokens, states, do_reduce, do_free, trace, non_term, config->known_count);\n");
+               fprintf(f, "\tvoid *rv = parser_run(tokens, states, do_reduce, do_free, trace, non_term, config);\n");
                fprintf(f, "\ttoken_close(tokens);\n");
                fprintf(f, "\treturn rv;\n");
                fprintf(f, "}\n\n");
@@ -1950,6 +1950,11 @@ This code needs to be able to store data somewhere.  Rather than requiring
 `do_reduce` to `malloc` that "somewhere", we pass in a large buffer and have
 `do_reduce` return the size to be saved.
 
+In order for the code to access "global" context, we pass in the
+"config" pointer that was passed to parser function.  If the `struct
+token_config` is embedded in some larger structure, the reducing code
+can access the larger structure using pointer manipulation.
+
 The code fragment requires translation when written out.  Any `$N` needs to
 be converted to a reference either to that buffer (if `$0`) or to the
 structure returned by a previous reduction.  These pointers need to be cast
@@ -2032,7 +2037,7 @@ automatically freed.  This is equivalent to assigning `NULL` to the pointer.
        {
                int i;
                fprintf(f, "#line 0 \"gen_reduce\"\n");
-               fprintf(f, "static int do_reduce(int prod, void **body, void *ret)\n");
+               fprintf(f, "static int do_reduce(int prod, void **body, struct token_config *config, void *ret)\n");
                fprintf(f, "{\n");
                fprintf(f, "\tint ret_size = 0;\n");
 
@@ -2561,9 +2566,10 @@ since the last state which could have been at the start of a line.
 ###### parser_run
        void *parser_run(struct token_state *tokens,
                         const struct state states[],
-                        int (*do_reduce)(int, void**, void*),
+                        int (*do_reduce)(int, void**, struct token_config*, void*),
                         void (*do_free)(short, void*),
-                        FILE *trace, const char *non_term[], int knowns)
+                        FILE *trace, const char *non_term[],
+                        struct token_config *config)
        {
                struct parser p = { 0 };
                struct token *tk = NULL;
@@ -2577,7 +2583,7 @@ since the last state which could have been at the start of a line.
                                tk = tok_copy(token_next(tokens));
                        p.next.sym = tk->num;
                        if (trace)
-                               parser_trace(trace, &p, tk, states, non_term, knowns);
+                               parser_trace(trace, &p, tk, states, non_term, config->known_count);
 
                        if (p.next.sym == TK_in) {
                                p.next.starts_indented = 1;
@@ -2627,7 +2633,7 @@ since the last state which could have been at the start of a line.
                                body = p.asn_stack +
                                        (p.tos - states[p.next.state].reduce_size);
 
-                               bufsize = do_reduce(prod, body, buf);
+                               bufsize = do_reduce(prod, body, config, buf);
 
                                pop(&p, size, do_free);
                                shift(&p, memdup(buf, bufsize), states);
@@ -2691,9 +2697,10 @@ since the last state which could have been at the start of a line.
 ###### exported functions
        void *parser_run(struct token_state *tokens,
                         const struct state states[],
-                        int (*do_reduce)(int, void**, void*),
+                        int (*do_reduce)(int, void**, struct token_config*, void*),
                         void (*do_free)(short, void*),
-                        FILE *trace, const char *non_term[], int knowns);
+                        FILE *trace, const char *non_term[],
+                        struct token_config *config);
 
 ### Tracing