From: NeilBrown Date: Sat, 31 May 2014 05:56:20 +0000 (+1000) Subject: parsergen: pass 'config' in to 'reduce' function. X-Git-Tag: workingparser~32 X-Git-Url: https://ocean-lang.org/code/?p=ocean;a=commitdiff_plain;h=4162be28cd4c149b595f9ec19f771523d0fa96e0 parsergen: pass 'config' in to 'reduce' function. 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 --- diff --git a/csrc/parsergen.mdc b/csrc/parsergen.mdc index f87e961..8e088b5 100644 --- a/csrc/parsergen.mdc +++ b/csrc/parsergen.mdc @@ -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