📄 output.cc
字号:
while ( level > 0 ){ putc( ')', output ); level --; }}static path_array paths;static int max_path_index = -1;static intfind_path_index( const path &p ){ int arraymax = max_path_index; int i; for ( i = 0; i <= arraymax; i++ ){ if ( p == paths[i] ){ return i; } } paths[i] = p; max_path_index = i; return i;}voidfind_nonterminals( struct ruletree *rtp, struct subgoal **sgpp, path p ){ path rightpath, leftpath; struct subgoal * sgp; switch( rtp->node->type() ){ case symbol::binaryop: // look down right subtree... rightpath = p; rightpath.descend( path::right ); find_nonterminals( rtp->right, sgpp, rightpath ); /* FALLTHROUGH */ case symbol::unaryop: // look down left subtree... leftpath = p; leftpath.descend( path::left ); find_nonterminals( rtp->left, sgpp, leftpath ); break; case symbol::terminal: // not here. break; case symbol::nonterminal: // found one. sgp = new (struct subgoal); sgp->p = p; sgp->sp = (nonterminal_symbol *)(rtp->node); sgp->next = *sgpp; *sgpp = sgp; break; }}voidprint_subgoal_description( FILE * output, FILE * data ){ rule * rp; rulelist_iterator r_i; struct subgoal * gp, *gp2; path q; int rulecost; int * first_action; int rule_index; int max_rule_index; int next_action_index; first_action = (int*)malloc( sizeof(int)*(all_rules.n()+1) ); assert( first_action != NULL ); fprintf(output, "extern const struct %s %s[];\n", action_pair_type_name, action_pairs); fprintf(output, "extern const struct %s %s[];\n", rule_action_type_name, rule_actions); fprintf(data, "const struct %s %s[]={\n", action_pair_type_name, action_pairs); r_i = all_rules; rule_index = 0; next_action_index = 0; int apIdx = 0; while ( (rp = r_i.next() ) != 0){ gp = NULL; first_action[rule_index++] = next_action_index; q.zero(); find_nonterminals( rp->rhs(), & gp, q ); while ( gp != 0 ){ // enumerate subgoals fprintf(data, " /* Action Pair %4d */ { %d, %d /* %s */ },\n", apIdx++, find_path_index( gp->p ), gp->sp->goal_number, gp->sp->name()); // loop housekeeping next_action_index += 1; gp2 = gp; gp = gp->next; delete gp2; } } // the one off-the-end, so we know how many goals in the last rule. // (see below) first_action[rule_index] = next_action_index; fprintf(data, "};\nconst struct %s %s[]={\n" " /* Rule Action 0 */ { 0, 0 },\n", rule_action_type_name, rule_actions); max_rule_index = rule_index; for (rule_index = 0; rule_index < max_rule_index; rule_index++){ fprintf(data, " /* Rule Action %4d */ { %d, %d },\n", rule_index+1, first_action[rule_index+1]-first_action[rule_index], first_action[rule_index] ); } fputs("};\n", data); free( first_action );}static voiddo_submatch_roots( FILE * output ){ path q; int pathno, maxpaths; static const char * submatch_root_rule =" submatch_roots = goal_top->submatch_roots;\n\ goal_top->curr_submatch_root = submatch_roots;\n\ for (i=0; i<subgoals_todo; i++){\n\ switch (app[i].pathno ){\n"; fprintf(output, submatch_root_rule); maxpaths = max_path_index; for ( pathno = 0; pathno <= maxpaths; pathno ++ ){ q = paths[pathno]; fprintf(output,"\t\tcase %d:\n\t\t submatch_roots[i]=", pathno ); print_down_path( output, q, handlename ); fputs( ";\n\t\t break;\n", output ); } fputs(" }\n }\n", output);}voidprint_synthesis( FILE * output ){ rule * rp; rulelist_iterator r_i; struct subgoal * gp, *gp2; path q; int pathno, maxpaths; int rulecost; static const char * prologue ="int\n\%s( %s %s, CVMJITCompilationContext* con)\n\{\n\ INITIALIZE_STACK_STATS(SYNTHESIS)\n\ int ruleno, subgoals_todo, goal, i;\n\ unsigned int stateno;\n\ const struct %s *app = NULL;\n\ struct %s* goal_top;\n\ %s *submatch_roots = NULL;\n\ INITIALIZE_GOAL_STACK;\n\ goal = goal_%s;\n"; static const char * start_rule ="start_rule:\n\ stateno = %s(%s);\n\ ruleno = %s[ CVMJIT_JCS_STATE_MASK(stateno) ][ goal ];\n\#ifdef CVMJIT_JCS_MATCH_DAG\n\ if (CVMJIT_JCS_DID_PHASE(stateno, CVMJIT_JCS_STATE_SYNTHED)){\n\ if (%s[ruleno]){\n\ /*\n\ CVMconsolePrintf(\">Synth: skipping node %%d rule %%d\\n\", CVMJITCompileExpression_thing_p->nodeID, ruleno);\n\ */\n\ goto skip_synth;\n\ }\n\ }\n\#endif\n\ if (ruleno == 0 ) {\n\#if defined(CVM_DEBUG) || defined(CVM_TRACE_JIT)\n\ con->errNode = %s;\n\#endif\n\ return -1;\n\ }\n\ subgoals_todo = %s[ruleno].n_subgoals;\n\ app = &%s[%s[ruleno].action_pair_index];\n\ goal_top->p = %s;\n\ goal_top->ruleno = ruleno;\n\ goal_top->subgoals_todo = subgoals_todo;\n\ goal_top->app = app;\n"; static const char * continue_rule ="continue_rule:\n\ if ( goal_top->subgoals_todo > 0 ){\n\ app = (goal_top->app)++;\n\ goal_top->subgoals_todo -= 1;\n\ %s = *goal_top->curr_submatch_root++;\n"; static const char * finish_continue_rule =" goal = app->subgoal;\n\ goal_top += 1;\n\ statsPushStack(SYNTHESIS);\n\ validateStack((goal_top < GOAL_STACK_TOP), Synthesis);\n\ goto start_rule;\n\ }\n\ %s = goal_top->p;\n\ submatch_roots = goal_top->submatch_roots;\n\ ruleno = goal_top->ruleno;\n"; static const char * finish_rule ="#ifdef CVMJIT_JCS_MATCH_DAG\n\ skip_synth:\n\#endif\n";static const char * epilogue ="#ifdef CVMJIT_JCS_MATCH_DAG\n\ CVMJIT_JCS_SET_STATE(%s, CVMJIT_JCS_STATE_SYNTHED);\n\#endif\n\ if ( !GOAL_STACK_EMPTY ){\n\ statsPopStack(SYNTHESIS);\n\ goal_top -= 1;\n\ goto continue_rule;\n\ }\n\ return 0;\n\}\n\n"; fprintf(output, prologue, synthesis_phase_name, nodetype, handlename, action_pair_type_name, rule_state_name, nodetype, goalname ); fprintf(output, start_rule, getfn, handlename, rule_to_use, rule_is_dag, handlename, rule_actions, action_pairs, rule_actions, handlename ); do_submatch_roots(output); fprintf(output, continue_rule, handlename ); fprintf(output, finish_continue_rule, handlename ); fprintf(output, finish_rule); do_synthesis( output ); fprintf(output, epilogue, handlename);}voidprint_satisfy_subgoals( FILE * output, int do_attributes ){ rule * rp; rulelist_iterator r_i; struct subgoal * gp, *gp2; path q; int pathno, maxpaths; int rulecost; static const char * prologue ="int\n\%s( %s %s, CVMJITCompilationContext* con)\n\{\n\ INITIALIZE_STACK_STATS(ACTION)\n\ int ruleno, subgoals_todo = 0, goal, i;\n\ unsigned int stateno;\n\ const struct %s *app = NULL;\n\ struct %s* goal_top;\n\ %s *submatch_roots = NULL;\n\ INITIALIZE_GOAL_STACK;\n\ goal = goal_%s;\n"; static const char * start_rule ="start_rule:\n\ /* Get the rule which can convert the current IRNode from its current\n\ state into a form that is expected by the desired goal: */\n\ stateno = %s(%s);\n\ ruleno = %s[ CVMJIT_JCS_STATE_MASK(stateno) ][ goal ];\n\#ifdef CVMJIT_JCS_MATCH_DAG\n\ if (CVMJIT_JCS_DID_PHASE(stateno, CVMJIT_JCS_STATE_SUBACTED)){\n\ if (%s[ruleno]){\n\ /*\n\ CVMconsolePrintf(\">Action: skipping node %%d rule %%d\\n\", CVMJITCompileExpression_thing_p->nodeID, ruleno);\n\ */\n\ goto skip_action_recursion;\n\ }\n\ }\n\#endif\n\ if (ruleno != 0 ) {\n\ /* Initialize the current goal: */\n\ subgoals_todo = %s[ruleno].n_subgoals;\n\ app = &%s[%s[ruleno].action_pair_index];\n\ goal_top->p = %s;\n\ goal_top->ruleno = ruleno;\n\ goal_top->subgoals_todo = subgoals_todo;\n\ goal_top->app = app;\n\ }\n"; static const char * continue_rule ="continue_rule:\n\ if ( goal_top->subgoals_todo > 0 ){\n\ app = (goal_top->app)++;\n\ goal_top->subgoals_todo -= 1;\n\ %s = *goal_top->curr_submatch_root++;\n"; static const char * finish_continue_rule =" goal = app->subgoal;\n\ goal_top += 1;\n\ statsPushStack(ACTION);\n\ validateStack((goal_top < GOAL_STACK_TOP), Action);\n\ goto start_rule;\n\ }\n\ %s = goal_top->p;\n\ submatch_roots = goal_top->submatch_roots;\n\ ruleno = goal_top->ruleno;\n"; static const char * finish_rule ="#ifdef CVMJIT_JCS_MATCH_DAG\n\ CVMJIT_JCS_SET_STATE(%s, CVMJIT_JCS_STATE_SUBACTED);\n\ skip_action_recursion:\n\#endif\n\#ifdef %s\n\ if (%s)\n\ fprintf(stderr, \"Applying rule %%d to node %%d\\n\",\n\ ruleno, id(%s) );\n\#endif\n\n";static const char * epilogue ="#ifdef CVMJIT_JCS_MATCH_DAG\n\ CVMJIT_JCS_SET_STATE(%s, CVMJIT_JCS_STATE_ACTED);\n\#endif\n\ if ( !GOAL_STACK_EMPTY ){\n\ statsPopStack(ACTION);\n\ goal_top -= 1;\n\ %s\n\ goto continue_rule;\n\ }\n\ return 0;\n\}\n\n"; fprintf(output, prologue, actionname, nodetype, handlename, action_pair_type_name, rule_state_name, nodetype, goalname ); fprintf(output, start_rule, getfn, handlename, rule_to_use, rule_is_dag, rule_actions, action_pairs, rule_actions, handlename ); do_submatch_roots(output); if ( do_attributes ){ fprintf( output, " goal_top->curr_attribute = goal_top->attributes;\n"); print_inheritance( output ); } fprintf(output, continue_rule, handlename ); fprintf(output, finish_continue_rule, handlename ); fprintf(output, finish_rule, handlename,debugmac, debugmac, handlename ); print_dorule( output ); fprintf(output, epilogue, handlename, do_attributes ? "goal_top->curr_attribute +=1;" : "" );}/* * aid to debugging program (and thus grammar and generator ) */static voidprint_printtree( FILE * output ){ /* * write out a data structure that corresponds to * our symbol table. It must give: * correspondence between opcode numbers and names; * unary/binary/terminal type info. * Given that, we can traverse the tree, printing out * node id's and opcodes and state #s, which is what we're * really after. */ symbol * sp; symbollist_iterator s_i = all_symbols; const char * typeword; static const char * prologue ="#ifdef %s\n\enum type { t_binary, t_unary, t_leaf, t_eot };\n\n\/* symbol table of node types */\n\struct symbol { int symval; char * symname; enum type t; };\n\\n\static struct symbol debug_symboltable[] = {\n"; /* end of symbol table and lookup code */ static const char * lookup = " { 0, 0, t_eot} };\n\n\void\n\%s( %s p )\n\{\n\ struct symbol * sp;\n\ char * symname;\n\ char buf[10];\n\\n\ /* look up symbol */\n\ for ( sp = debug_symboltable; sp->t != t_eot; sp ++ )\n\ if (%s(con, p) == sp->symval) break;\n\ if ( sp->t == t_eot ){\n\ sprintf( buf, \"<%%d>\", %s(con, p) );\n\ symname = buf;\n\ } else \n\ symname = sp->symname;\n\ /* now print out what we got */\n\ fprintf( stderr, \"(%%s [%%d] state %%d \", symname, id(p), %s(p));\n\ switch (sp->t){\n\ case t_binary:\n\ %s( %s(p) );\n\ %s( %s(p) );\n\ break;\n\ case t_unary:\n\ %s( %s(p) );\n\ break;\n\ }\n\ fputs( \" ) \", stderr );\n\}\n\#endif\n\n"; fprintf( output, prologue, debugmac ); /* print out symbol table */ while ( ( sp = s_i.next() ) != 0 ){ switch ( sp->type() ){ case symbol::binaryop: typeword = "t_binary"; break; case symbol::unaryop: typeword = "t_unary"; break; case symbol::terminal: typeword = "t_leaf"; break; case symbol::nonterminal: continue; // nonterminals don't appear in trees. } fprintf( output, "\t{ %s, \"%s\", %s },\n", sp->name(), sp->name(), typeword ); } fprintf( output, lookup, printtree, nodetype, opfn, opfn, getfn, printtree, leftfn, printtree, rightfn, printtree, leftfn );}voidprint_output_file( FILE* output, FILE* data, FILE* header, const char* header_name ){ int goalno; setup_output(); print_header(output, data, header, header_name); print_transition_tables(const_stateno_type(), output, data ); if (is_dag) print_dagrule_array( output, data ); print_match(stateno_type(), output ); goalno = print_action_matrix( output, data ); /* We have to wait till after print_action_matrix() to print the rules macros list because print_rules_macros_list() depends on print_action_matrix() to set the is_reached flag in each rule: */ print_rules_macros_list(header); fclose(header); print_subgoal_description( output, data ); if ( do_attributes ){ print_synthesis( output ); } print_satisfy_subgoals( output, do_attributes ); print_printtree( output );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -