void run_grammar(tx_grammar_literal *lit) { size_t i; int row, col; pixel px; tx_grammar_literal *chosen = NULL; tx_grammar_expansion_site *ges = NULL; // Create a list of expansion sites: list *expansion_sites = create_list(); // Start by loading our source file into our result texture and calling our // pre-processing filter if we have one: if (lit->filename == NULL) { if (lit->anchor_x == 0 || lit->anchor_y == 0) { fprintf( stderr, "Error: grammar with NULL filename must have nonzero anchor values.\n" ); fprintf(stderr, "(found: %zu, %zu)\n", lit->anchor_x, lit->anchor_y); exit(EXIT_FAILURE); } lit->result = create_texture(lit->anchor_x, lit->anchor_y); } else { lit->result = load_texture_from_png(lit->filename); } if (lit->preprocess != NULL) { (*(lit->preprocess))(lit->result, lit->preargs); } // Now expand each child reference at random. Note that due to the low // resolution of the pseudo-random process, any item with a weight of less // than 1/65536th of the total weight of all items in a disjunction will // never be picked. for (col = 0; col < lit->result->width; ++col) { for (row = 0; row < lit->result->height; ++row) { px = tx_get_px(lit->result, col, row); for (i = 0; i < N_GRAMMAR_KEYS; ++i) { if (px == GRAMMAR_KEYS[i] && lit->children[i] != NULL) { chosen = choose_child( lit->children[i], hash_3d(hash_2d(hash_1d((ptrdiff_t) lit), i), col, row) ); if (chosen->result == NULL) { run_grammar(chosen); } ges = create_expansion_site(); ges->col = col; ges->row = row; ges->literal = chosen; l_append_element(expansion_sites, ges); ges = NULL; // destroy_list later on takes care of the memory used. } } } } l_witheach(expansion_sites, (void *) lit, expand_literal_into); // Clean up our list of expansion sites: destroy_list(expansion_sites); // Before wrapping up call our post-processing function if it exists: if (lit->postprocess != NULL) { (*(lit->postprocess))(lit->result, lit->postargs); } }
static VALUE run_gazelle_parse(VALUE self, VALUE input, bool run_callbacks) { VALUE compiled_file_stream = rb_iv_get(self, "@filename"); char *filename = RSTRING_TO_PTR(compiled_file_stream); char *input_string = RSTRING_TO_PTR(input); if (run_grammar(self, filename, input, input_string, run_callbacks)) return Qfalse; return(terminal_error ? Qfalse : Qtrue); }