📄 output.cc
字号:
/* * @(#)output.cc 1.53 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */// @(#)output.cc 2.25 99/07/14#include <string.h>#include <stdio.h>#include "wordlist.h"#include "globals.h"#include "symbol.h"#include "state.h"#include "item.h"#include "path.h"#include "assert.h"#include "transition.h"#include "rule.h"#include "ARRAY.h"extern wordlist invert_state( const state * sp );/* * This is not a class -- just a file full of stuff. * * This is real output: called to make real output files if we get * that far. */DERIVED_ARRAYwoC(path_array, path);static const char *small_int_type( unsigned v ){ // assuming 2's complement representation, and that // typecasts properly trim bits..# define BITS (-1L) if ( v <= (unsigned char)BITS ) return "unsigned char"; else if ( v <= (unsigned short)BITS ) return "unsigned short"; else if ( v <= (unsigned int)BITS ){ assert ( v <= (unsigned int)BITS ); return "unsigned int"; }# undef BITS}static const char *const_small_int_type( unsigned v ){ // assuming 2's complement representation, and that // typecasts properly trim bits..# define BITS (-1L) if ( v <= (unsigned char)BITS ) return "const unsigned char"; else if ( v <= (unsigned short)BITS ) return "const unsigned short"; else if ( v <= (unsigned int)BITS ){ assert ( v <= (unsigned int)BITS ); return "const unsigned int"; }# undef BITS}static const char *stateno_type(){ return small_int_type( (unsigned)allstates.n() );}static const char *const_stateno_type(){ return const_small_int_type( (unsigned)allstates.n() );}/* * variable and function names are constructed from a number of * things: generally we use the cgname + terminal name + function. * Names are sometimes construced in print routines, from templates * provided by the caller. Here we consturct some of those templates * from cgname, so it doesn't have to be know further. */static char * transition_name_template;static char * map_name_template;static char * matchname;static char * handlename;static char * rule_to_use;static char * rule_actions;static char * action_pairs;static char * actionname;static char * debugmac;static char * printtree;static char * action_pair_type_name;static char * rule_action_type_name;static char * match_state_name;static char * rule_state_name;static char * synthesis_phase_name;static char * rule_is_dag;static int output_is_setup = 0;static char *catiname( const char * proto ){ char * name_template; // malloc space // catinate cgname with the proto. // return result. name_template = (char*)malloc( strlen(cgname) + strlen(proto) + 1 ); assert( name_template != 0 ); strcpy( name_template, cgname ); strcat( name_template, proto ); return name_template;}static voiddefit( char ** loc, const char * default_val ){ if (*loc == 0) *loc = (char *) default_val;}static voidconstruct_name_templates(){ transition_name_template = catiname( "_%s_transition" ); map_name_template = catiname( "_%s_%s_map" ); matchname = catiname( "_match" ); handlename = catiname( "_thing_p" ); rule_to_use = catiname( "_rule_to_use" ); rule_actions = catiname( "_rule_actions" ); action_pairs = catiname( "_action_pairs" ); actionname = catiname( "_action" ); debugmac = catiname( "_DEBUG" ); printtree = catiname( "_printtree" ); action_pair_type_name = catiname("_action_pairs_t"); rule_action_type_name = catiname("_rule_action"); match_state_name = catiname("_match_computation_state"); rule_state_name = catiname("_rule_computation_state"); synthesis_phase_name = catiname("_synthesis"); rule_is_dag= catiname("_isdag");}static voidsetup_output(){ if ( output_is_setup != 0 ) return; // housekeeping... // make sure goalname and nodetype and cgname are defined to // something... defit( &cgname, "pmatch"); defit( &nodetype, "nodep_t"); defit( &opfn, "OPCODE" ); defit( &rightfn, "RIGHT"); defit( &leftfn, "LEFT"); defit( &getfn, "GETSTATE"); defit( &setfn, "SETSTATE"); construct_name_templates(); output_is_setup = 1;}/* * Special case transition-table output. * Largely copied from unary_transition::print */static voidprint_direct_map_unary_transition( statemap *sm, unary_transition *ut, const char * statetype, const char * symbol_name, const char * name_template, FILE *output, FILE *data ){ int maxstates = sm->max_ordinate(); int i, count = 0; stateno * state = ut->state; /* * Note: The following assertion will keep us from * getting into trouble in the short run, if * we have DAG management. You can take this assertion * out, but BE SURE that all the places you extract the * state number to use as an index it gets properly * masked using CVMJIT_JCS_STATE_MASK(v). */ assert( maxstates <= 255 ); /**************************************************/ fprintf(output, "extern %s\t", statetype); fprintf(output, name_template, symbol_name ); fprintf(output, "[%d];\n", maxstates+1); fprintf(data, "%s\n", statetype); fprintf(data, name_template, symbol_name ); fprintf(data, "[%d] =\n", maxstates+1); fprintf(data, "{ "); for (i=0; i<maxstates; i++) { print_statenumber( data, state[(*sm)[i]], ","); count += 1; if (count % 20 == 0) { fputs("\n", data); } } print_statenumber(data, state[(*sm)[i]], " };\n\n");}/* * Print definitions of transition tables, including state maps. */voidprint_transition_tables( const char * statetype, FILE *output, FILE *data ){ symbollist_iterator s_i = all_symbols; symbol *sp; statemap *lhs, *rhs; unary_transition *ut; const char * maptype; setup_output(); while( (sp = s_i.next() ) != 0){ switch (sp->functional_type()){ case symbol::unaryop: case symbol::rightunaryop:{ if (sp->type() == symbol::unaryop ){ unary_symbol * usp = ((unary_symbol *)sp); lhs = &usp->lhs_map; ut = usp->transitions; } else { binary_symbol * bsp = ((binary_symbol *)sp); lhs = &bsp->lhs_map; ut = (unary_transition*)(bsp->transitions); } maptype = const_small_int_type( lhs->max_mapping() ); if ( maptype == statetype ){ print_direct_map_unary_transition( lhs, ut, statetype, sp->name(), transition_name_template, output, data ); sp->direct_map_transitions = 1; } else { lhs->print( maptype, sp->name(), "l", map_name_template, output, data ); ut->print( statetype, sp->name(), transition_name_template, output, data ); } break; } case symbol::binaryop:{ binary_symbol * bsp = ((binary_symbol *)sp); lhs = &bsp->lhs_map; rhs = &bsp->rhs_map; lhs->print( const_small_int_type( lhs->max_mapping() ), sp->name(), "l", map_name_template, output, data ); rhs->print( const_small_int_type( rhs->max_mapping() ), sp->name(), "r", map_name_template, output, data ); bsp->transitions->print( statetype, sp->name(), transition_name_template, output, data ); break; } case symbol::nonterminal: // no tables break; case symbol::terminal: // don't bother: it's only a scalar... break; } }}static voidprint_dagrule_array( FILE *output, FILE *data ){ int nrules = all_rules.n(); int item_this_line; rulelist_iterator r_iter; rule *rp; fprintf( output, "extern const char %s[ %d ];\n", rule_is_dag, nrules ); fprintf( data, "const char %s[] = {\n 0, ", rule_is_dag); r_iter = all_rules; item_this_line = 1; while ( (rp = r_iter.next() ) != 0){ if ( item_this_line >= 20 ){ fprintf( data, "\n "); item_this_line = 0; } fprintf( data, rp->is_dag()? "1, ": "0, "); item_this_line += 1; } fprintf(data, "\n};\n");}static voidprint_mapped_subscript( const char * sym_name, const char * designator, const char * subscript, FILE * out ){ putc( '[', out ); fprintf( out, map_name_template, sym_name, designator ); fprintf( out, "[%s]]", subscript );}/* * print out the header file full of shared data types. *static char * action_pair_type_name;static char * rule_action_type_name;static char * match_state_name;static char * rule_state_name; */static voidprint_codegen_proto(FILE * output, const char *pass, int with_semi){ static const char *prototype = "int\n%s_%s( %s root, CVMJITCompilationContext* con )%s\n"; fprintf( output, prototype, cgname, pass, nodetype, with_semi ? ";" : "");}/* Purpose: Dump the macros list for all the rules that are defined. */static voidprint_rules_macros_list(FILE* header_file){ rule *rp; rulelist_iterator r_iter; int rule_is_reached; r_iter = all_rules; while ( (rp = r_iter.next() ) != 0){ wordlist *macros_list = rp->get_macros_list(); if (macros_list == NULL) { continue; } rule_is_reached = rp->get_reached(); fprintf(header_file, "/* Macros list for rule "); rp->print(header_file, true); fprintf(header_file, ": */\n"); if ( ! rule_is_reached ){ fprintf(header_file, "#ifdef CVM_CG_EXPAND_UNREACHED_RULE\n"); } /* Dump the macros list: */ { word_iterator wi = *macros_list; const char * p; static const char macro_declaration[] = "#ifndef %s\n" "#define %s\n" "#endif\n"; while ( ( p = wi.next() ) != 0 ){ fprintf(header_file, macro_declaration, p, p); } } if ( ! rule_is_reached ){ fprintf(header_file, "#endif /*CVM_CG_EXPAND_UNREACHED_RULE*/\n"); } fprintf(header_file, "\n"); }}static voidprint_header( FILE * output, FILE * data, FILE* header_file, const char* header_name){ static const char * prototype1 ="#ifndef INCLUDED_%s\n\#define INCLUDED_%s\n\ /* MACHINE GENERATED -- DO NOT EDIT DIRECTLY! */ \n\/* Possible error states returned by CVMJITCompileExpression. */\n\#define JIT_IR_SYNTAX_ERROR -1\n\#define JIT_RESOURCE_NONE_ERROR -2\n\n\#ifndef IN_%s_DATA\n\struct %s { \n\ int opcode; \n\ %s p; \n\ %s subtrees[2]; \n\ int which_submatch; \n\ int n_submatch; \n\}; \n\\n\struct %s { \n\ %s p; \n\ int ruleno; \n\ int subgoals_todo; \n\ const struct %s* app; \n";static const char * prototype2 ="}; \n\n";static const char * prototype3 = "\n#endif\n\\n\struct %s { \n\ unsigned short pathno;\n\ unsigned short subgoal;\n\}; \n\\n\struct %s {\n\ unsigned short n_subgoals;\n\ unsigned short action_pair_index;\n\};\n\\n\#endif\n\\n"; fprintf(header_file, prototype1, cgname, cgname, cgname, /* the ifdef parts */ match_state_name, nodetype, nodetype, /* the match state */ rule_state_name, nodetype, action_pair_type_name /* rule state */ ); fprintf(header_file, "#define %s_MAX_ARITY %d\n", cgname, max_rule_arity); fprintf(header_file, " CVMJITIRNodePtr * curr_submatch_root;\n", cgname, cgname ); fprintf(header_file, " CVMJITIRNodePtr submatch_roots[%s_MAX_ARITY];\n", cgname, cgname ); if (do_attributes){ fprintf(header_file, " %s_attribute * curr_attribute;\n", cgname ); fprintf(header_file, " %s_attribute attributes[%s_MAX_ARITY];\n", cgname, cgname ); } fprintf(header_file, prototype2); print_codegen_proto(header_file, "match", 1); if (do_attributes) { print_codegen_proto(header_file, "synthesis", 1); } print_codegen_proto(header_file, "action", 1); fprintf(header_file, prototype3, action_pair_type_name, rule_action_type_name ); fprintf(output, "#include \"%s\"\n", header_name); fprintf(data, "#define IN_%s_DATA\n", cgname); fprintf(data, "#include \"%s\"\n", header_name);}/* * Print the bottom up pattern match * machinery. Avoid recursion in the generated program * by managing our own stack. */static voidprint_match( const char * statetype, FILE * output){ symbollist_iterator s_i = all_symbols; symbol *symp; /* dag management assumes that there will be no more than * 4000 states! */ static const char * dag_management ="#define CVMJIT_JCS_MATCH_DAG\n\#define CVMJIT_JCS_STATE_MASK(v) (v & 0x0fff)\n\#define CVMJIT_JCS_STATE_MATCHED 0x1000\n\#define CVMJIT_JCS_STATE_SYNTHED 0x2000\n\#define CVMJIT_JCS_STATE_SUBACTED 0x4000\n\#define CVMJIT_JCS_STATE_ACTED 0x8000\n\#define CVMJIT_JCS_SET_STATE(p, flag) %s(p, %s(p)|flag)\n\#define CVMJIT_JCS_DID_PHASE(v, flag) (((v) & (flag)) != 0)\n\#define CVMJIT_DID_SEMANTIC_ACTION(p) (CVMJIT_JCS_DID_PHASE(%s(p), CVMJIT_JCS_STATE_ACTED))\n\";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -