/************************************************************************** * PROJECT: DEMETER * MODULE: GENERATION * FILE: gen_pprt.c *-------------------------------------------------------------------------- * COPYRIGHT (c) 1990 Northeastern University * Prof. Karl J. Lieberherr *-------------------------------------------------------------------------- * AUTHOR: Walter Hursch * * DATE: January 17, 1990 * REVISED: * April 1992 * Updated because of a bug in GNU C++ compiler * November 9, 1992 * Enable components and external libraries * * *-------------------------------------------------------------------------- * DESCRIPTION: * Gen_pprt generates for each class C of the class dictionary the * implemention of a method called pp() which pretty prints the object * represented in class C. * Gen_pprt appends the function to the implementation file C_DEM.C . * **************************************************************************/ /************************************************************************** Data dictionary P1 ;;; produced by extract-cd 'O-P1' ; P1 : I-P1: cd ; : O-P1: intermediate notation ;;; O-P1=I-P2 Demeter_in = Input. Input : Cd_graph *common*. Cd_graph = < adjacencies > Nlist(Adjacency) ["*terminal_sets*" Comma_list(Vertex) "."] . Adjacency = < source > Vertex < ns > Neighbors ["*inherits_from*" Comma_list(Term)] "." . Neighbors_wc : Construct_ns | Alternat_ns *common* < construct_ns > List(Any_vertex). Neighbors : Neighbors_wc | Repetit_n | Intermediate_ns *common*. Intermediate_ns : Repetit | Non_repetit *common* . Non_repetit : Instantiable | Abstract *common* List(Int_part). Instantiable = "instantiable=". Repetit = "repetition=" Term [ Non_empty]. Non_empty = "*non_empty*". Abstract = "abstract=". Int_part : Required_int_part | Optional_int_part *common* Labeled. Required_int_part = "*required*". Optional_int_part = "*optional*". Construct_ns = "=". Alternat_ns = ":" < alternat_ns > Bar_list(Term) [ Common]. Common = "*common*". Repetit_n = "~" Sandwich(Kernel). Kernel = [ Term ] "{" Sandwich(Term) "}". Any_vertex : Opt_labeled_term | Optional_term | Syntax_vertex | Inherit_term *common*. Vertex = < vertex_name > Ident . Syntax_vertex : Regular_syntax | Print_command *common*. Regular_syntax = < string > String . Print_command : Print_indent | Print_unindent | Print_skip | Print_space *common*. Print_indent = "+" . Print_unindent = "-" . Print_skip = "*l" . Print_space = "*s" . Opt_labeled_term : Labeled | Regular *common* Term. Regular = . Labeled = "<" < label_name > Ident ">" . Inherit_term = "*inherit*" Comma_list(Term). ;; ;; 11/5/92 Update term to contain component and external terms ;; Term : Normal | CppTerm *common* Vertex TermRef ["(" Comma_list(Term) ")" ]. CppTerm = "$" . Normal = . TermRef : LocalRef | ModuleRef. ModuleRef : CompRef | LibRef *common* Ident. LocalRef = . CompRef = "@". LibRef = "@@". Optional_term = "[" Sandwich(Opt_labeled_term) "]". List(S) ~ {S}. Nlist(S) ~ S {S}. Bar_list(S) ~ S {"|" S}. Comma_list(S) ~ S {"," S}. Sandwich(S) = List(Syntax_vertex) S List(Syntax_vertex). **************************************************************************/ #include "generate.h" extern int term_memberfunc( Universal* term1, Universal* term2 ); /*------------------------------------------------------------------------- * Method: void gen_pprt( char* path ) * * Generate the pretty print function pp() for every class in the class * dictionary. *-----------------------------------------------------------------------*/ /* * demeter_in = < input > input . */ void Demeter_in::gen_pprt( char* target ) { input -> gen_pprt( target ); } /* * input : cd_graph *common* . */ void Input::gen_pprt( char* ) { } /* * cd_graph = < adjacencies > adjacency-Nlist * [ "*terminal_sets*" < terminal_sets > vertex-comma_List "." ] . */ void Cd_graph::gen_pprt( char* target ) { DBG( cout << "IN Cd_graph::gen_pprt" << endl ); adjacencies -> gen_pprt( target ); DBG( cout << "OUT Cd_graph::gen_pprt" << endl ); } /* * adjacency-Nlist ~ adjacency { adjacency } . */ void Adjacency_Nlist::gen_pprt( char* target ) { const int MAXPATH = 256; Adjacency_list_iterator next_arg( *this ); Adjacency_ each_arg; ofstream outFile; outFile.open( target, ios::app ); if ( !outFile ) { cerr << "cannot open " << target << " for output.\n"; exit( -1 ); } while ( each_arg = next_arg() ) each_arg -> gen_pprt( outFile, this ); outFile.close(); } /*------------------------------------------------------------------------- * Method: * void gen_pprt( ofstream& outFile, Adjacency_Nlist* adj_list ) * * Go further down the graph to Instantiable, Abstract and Repetit. * *-----------------------------------------------------------------------*/ /* * adjacency = < source > vertex < ns > neighbors * [ "*inherits_from*" < inherits_from > term-comma_List ] "." . */ void Adjacency::gen_pprt( ofstream& outFile, Adjacency_Nlist* adj_list ) { ns -> gen_pprt( outFile, adj_list, this ); } /* * neighbors : neighbors_wc | repetit_n | intermediate_ns *common* . */ void Neighbors::gen_pprt( ofstream&, Adjacency_Nlist*, Adjacency* ) { } /* * neighbors_wc : construct_ns | alternat_ns * *common* < construct_ns > any_vertex-List . */ void Neighbors_wc::gen_pprt ( ofstream& outFile, Adjacency_Nlist* adj_list, Adjacency* adj ) { outFile << "\n\nvoid " << adj -> get_class_name() << "::pp( ostream& strm ) const\n{\n"; construct_ns -> gen_pprt( outFile ); /* get superclass, if any, and have pp invoke pp of superclass remember: this is still single inheritance version! */ Normal *n_normal = new Normal(); n_normal -> set_vertex( adj -> get_source() ); TermRef *n_termRef = new LocalRef(); n_normal -> set_moduleRef( n_termRef ); Adjacency *base = adj_list -> get_base_class_of( n_normal ); if ( base ) { outFile << " " << base -> get_class_name() << "::pp( strm );\n"; } outFile << "}\n\n"; } /* * repetit_n = "~" < Sandwiched > kernel-Sandwich . */ void Repetit_n::gen_pprt ( ofstream& outFile, Adjacency_Nlist*, Adjacency* adj ) { outFile << "\n\nvoid " << adj -> get_class_name() << "::pp( ostream& strm ) const\n{\n"; sandwiched ->gen_pprt( outFile ); outFile << "}\n\n"; } /* * kernel-Sandwich = < first > syntax_vertex-List < inner > kernel * < second > syntax_vertex-List . */ void Kernel_Sandwich::gen_pprt( ofstream& outFile ) { first -> gen_pprt( outFile ); inner -> gen_pprt( outFile ); second -> gen_pprt( outFile ); } /* * kernel = [ < nonempty > term ] "{" < repeated > term-Sandwich "}" . */ void Kernel::gen_pprt( ofstream& outFile ) { char *classname = repeated -> get_class_name(); /* templates outFile << " D__linked_list_iterator<" << classname << "> next_" << classname << "( this );\n" << " " << classname << "* each_" << classname << ";\n"; if ( nonempty ) { outFile << " next_" << classname << "() -> pp( strm );\n"; } outFile << " while ( each_" << classname << " = next_" << classname << "() ) {\n"; END templates */ /* BEGIN non-template */ outFile << " " << classname << "_list_iterator next_" << classname << "( *this );\n" << " " << classname << "_ each_" << classname << ";\n"; if ( nonempty ) { outFile << " next_" << classname << "() -> pp( strm );\n"; } outFile << " while ( each_" << classname << " = next_" << classname << "() ) {\n"; /* END non-template */ repeated -> gen_pprt( outFile ); outFile << " }\n"; } /* * term-Sandwich = < first > syntax_vertex-List < inner > term * < second > syntax_vertex-List . */ void Term_Sandwich::gen_pprt( ofstream& outFile ) { first -> gen_pprt( outFile ); outFile << " each_" << this -> get_class_name() << " -> pp( strm );\n"; second -> gen_pprt( outFile ); } char *Term_Sandwich::get_class_name() { return ( inner -> get_class_name() ); } /* * syntax_vertex-List ~ { syntax_vertex } . */ void Syntax_vertex_List::gen_pprt( ofstream& outFile ) { Syntax_vertex_list_iterator next_arg( *this ); Syntax_vertex_ each_arg; while ( each_arg = next_arg() ) each_arg -> gen_pprt( outFile ); } /* * any_vertex-List ~ { any_vertex } . */ void Any_vertex_List::gen_pprt( ofstream &outFile ) { Any_vertex_list_iterator next_arg( *this ); Any_vertex_ each_arg; while ( each_arg = next_arg() ) each_arg -> gen_pprt( outFile ); } /* * any_vertex : opt_labeled_term | optional_term | syntax_vertex | * inherit_term *common* . */ void Any_vertex::gen_pprt( ofstream& ) { } /* * optional_term = "[" < opt > opt_labeled_term-Sandwich "]" . */ void Optional_term::gen_pprt( ofstream& outFile ) { outFile << " if ( " << opt -> get_inner_var_name() << " ) {\n"; opt -> gen_pprt( outFile ); outFile << " }\n"; } /* * opt_labeled_term-Sandwich = < first > syntax_vertex-List * < inner > opt_labeled_term * < second > syntax_vertex-List . */ void Opt_labeled_term_Sandwich::gen_pprt( ofstream& outFile ) { first -> gen_pprt( outFile ); inner -> gen_pprt( outFile ); second -> gen_pprt( outFile ); } /* * opt_labeled_term : labeled | regular *common* < vertex > term . * * Assumption: all opt_labeled_terms are labeled. Guaranteed by cd-param-exp. */ int Opt_labeled_term::is_NonDemTerm() { return ( vertex -> is_NonDemTerm() ); } void Opt_labeled_term::gen_pprt( ofstream& outFile ) { if ( ! this->is_NonDemTerm() ) { outFile << " " << this -> get_labeled() -> get_var_name() << " -> pp( strm );" << endl; } else { outFile << " cout << \"external part\"; " << endl; } } char *Opt_labeled_term_Sandwich::get_inner_var_name() { return ( inner -> get_inner_var_name() ); } char *Opt_labeled_term::get_inner_var_name() { return ( this -> get_labeled() -> get_var_name() ); } /* * syntax_vertex : regular_syntax | print_command *common* . */ void Syntax_vertex::gen_pprt( ofstream& ) { } /* * regular_syntax = < string > string . */ void Regular_syntax::gen_pprt( ofstream& outFile ) { outFile << " strm << \"" << string -> get_val() << "\";\n"; } /* * print_command : print_indent | print_unindent | print_skip | print_space * *common* . */ void Print_command::gen_pprt( ofstream& ) { } /* * print_indent = "+" . */ void Print_indent::gen_pprt( ofstream& outFile ) { outFile << " strm << \"\\t\";\n"; } /* * print_unindent = "-" . */ void Print_unindent::gen_pprt( ofstream& outFile ) { outFile << " strm << \"\\b\\b\\b\\b\";\n"; } /* * print_skip = "*l" . */ void Print_skip::gen_pprt( ofstream& outFile ) { outFile << " strm << \"\\n\";\n"; } /* * print_space = "*s" . */ void Print_space::gen_pprt( ofstream& outFile ) { outFile << " strm << \" \";\n"; } /* * adjacency-Nlist ~ adjacency { adjacency } . */ Adjacency* Adjacency_Nlist::get_base_class_of( Term* derived ) { Adjacency_list_iterator next_Adj( *this ); Adjacency_ each_Adj; while ( each_Adj = next_Adj() ) { if ( each_Adj -> is_base_class_of( derived ) ) { return ( each_Adj ); } } return NULL; } /* * adjacency = < source > vertex < ns > neighbors * [ "*inherits_from*" < inherits_from > term-comma_List ] "." . */ int Adjacency::is_base_class_of( Term* derived ) { return ( ns -> is_base_class_of( derived ) ); } /* * neighbors : neighbors_wc | repetit_n | intermediate_ns *common* . */ int Neighbors::is_base_class_of( Term* ) { return 0; } /* * alternat_ns = ":" < alternat_ns > term-bar_List [ < common > common ] . */ int term_memberfunc( Universal*, Universal* ); int Alternat_ns::is_base_class_of( Term* derived ) { return( alternat_ns -> member(derived, term_memberfunc) ); }