// Propagation Pattern Translator // // By: Michael Theroux // Michael Ruelle // Jim Pappas // // A program that converts propagation patterns into traversal-visitor // syntax that can be compiled by demjava. // // COM1205 // 4/97 //-------------------------------------------------------------------- // InTraversalPP is our main class in our Class Dictionary. This class // contains our class dictionary. // // It contains 5 main traversal used to gather information from the // propagation pattern: // // traversal getGeneralInformation( GeneralInformationVisitor iv ) // traversal getPathDirectives( PathDirectiveVisitor pdv ) // traversal getClassWrapperInformation( // CWrapInfoVis cwiv, EWrapInfoVis ewiv ) // traversal getInitializationList( InitializationVisitor initVis ) // // getGeneralInformation is the most important traversal. It gathers // general information about the propagation pattern. This includes // a list of all arguments and transportation variables. // // getPathDirectives gathers information about Through and Bypass // directives. // // getClassWrapperInfomation gathers information about class and edge // wrappers. // // getInitializationList gather a different list of transportation variables // used in the intialization of transportation variables in the final // result. InTraversalPP { (@ public void translate(String cdname, String ppname) throws Exception{ // First we gather the general information from the class //create out General Information Visitor GeneralInformationVisitor iv = new GeneralInformationVisitor( new ClassListVector(), new VariableListVector(), new ArgumentClassListVector(), new ArgumentVariableListVector(), new ReturnValueType( new Ident( "void" )), new ClassName( new Ident("") ), new TraversalName( new Ident("")), null, new TargetVectorList() ); this.getGeneralInformation( iv ); // Now we gather information about the Class and Edge // wrappers. // create our Class Wrapper Information Visitor CWrapInfoVis cwiv = new CWrapInfoVis ( new WrapperPrefixList(), new WrapperPrefix(), new WrapperCodeList(), new WrapperClassListList(), new WrapperClassList() ); // Create our Edge Wrapper Information Visitor EWrapInfoVis ewiv = new EWrapInfoVis ( new WrapperPrefixList(), new WrapperPrefix(), new WrapperCodeList(), new WrapperClassListList(), new WrapperClassList(), new WrapperEdgeTypes(), new WrapperEdgeType() ); getClassWrapperInformation( cwiv, ewiv ); // Now we gather information about the bypass and through // directives. // Create out Path Directive Visitor PathDirectiveVisitor pdv = new PathDirectiveVisitor ( new Directives(), new DirectiveClassesList(), new DirectiveEdgesList(), new DirectiveClasses() ); getPathDirectives( pdv ); // Now we get the initialization list we need InitializationVisitor iiv = new InitializationVisitor( new ClassListVector(), new VariableListVector()); getInitializationList( iiv ); // Now we can output the new information necessary in the class // dictionary // Create a skeleton for our class dictionary output OutCD cd = OutCD.parse( "" ); // create file handles for the tmp file and the cd file // these handles are needed in order to append the old cd file // to the new cd file with our additions. File cdfile1= new File(cdname + ".cd"); File cdfile2= new File(cdname + ".cd.tmp"); File cdfile3= new File(cdname + ".cd"); // rename the old cdfile to the tmp file cdfile1.renameTo(cdfile2); // create a new DataStream to read in the old cd (tmp file) DataInputStream fin = new DataInputStream( new FileInputStream(cdfile2)); // create a file output stream to wrap a printstream around // to output our new cd file FileOutputStream fout = new FileOutputStream(cdfile3); PPtrans.out = new PrintStream(fout); // read in from the old cd file, byte by byte, and then print it out // to the new cd file. We cannot read in as char because the readChar // method reads only UTF chars (2 byte) // uses the end of file exception becuase no end of file method // in class File. byte bin; while (true){ try { bin = fin.readByte(); PPtrans.out.print((char)bin); } catch (EOFException e) { break; } } // output our class dictionary PPtrans.out.println(); PPtrans.out.println( "// CLASS DICTIONARY Addins" ); PPtrans.out.println(); ClassDictionaryVisitor cdv =new ClassDictionaryVisitor( iv ); cd.create( cdv ); // Finally, we output our behavior file. // output our behavior file File behfile=null; behfile= new File(ppname + ".beh"); PPtrans.out = new PrintStream(new FileOutputStream(behfile)); PPtrans.out.println(); PPtrans.out.println( "// BEHAVIOR FILE" ); PPtrans.out.println(); OutTraversal ot = OutTraversal.parse(""); PrintingVisitor pv = new PrintingVisitor( iv, cwiv, ewiv, pdv, iiv, new TabCount( new Integer( 0 ) ), new WrapperCount( new Integer( 0 ) )); ot.translate( pv ); } @) // our notorious traversals traversal getGeneralInformation( GeneralInformationVisitor iv ){ to *; } traversal getPathDirectives( PathDirectiveVisitor pdv ){ to {InThroughDirective, InBypassDirective}; } traversal getClassWrapperInformation( CWrapInfoVis cwiv, EWrapInfoVis ewiv ) { to InWrapper; } traversal getInitializationList( InitializationVisitor initVis ){ to { InVariable, InJavaTypeName }; } } // This is the main class used for our Class Dictionary output. // It contains only one traversal, which is a minature printing // traversal that output the Class Dictionary. OutCD { traversal create( ClassDictionaryVisitor cdv ){ to OutTraversalSpecification; } } // ClassDicitionaryVisitior // // This is the printing-visitor for the class dictionary. ClassDictionaryVisitor { before OutTraversalSpecification (@ int size = giv.get_classList().size(); PPtrans.out.print( "TraversalVisitor" ); PPtrans.out.print( giv.get_traversalName().get_name() + " = " ); if( !giv.get_type().get_type().equals( new Ident( "void" ) )){ PPtrans.out.print( "" ); PPtrans.out.print( giv.get_type().get_type() ); } // Output transportation Variables declared for( int i = 0; i < size; i++ ) { Ident variableName = (Ident)giv.get_variableList(). elementAt( i ); Ident className = (Ident)giv.get_classList(). elementAt( i ); // We have to do this because we only want the first // transporation variable class listed with the name // of the first transportation variable declared. // ------------------------------------------------- int indexOfName = giv.get_classList(). indexOf( className ); if( ((Ident)giv.get_variableList().elementAt( indexOfName )). equals( variableName ) ) { // ------------------------------------------------ PPtrans.out.print( " <" ); PPtrans.out.print( variableName ); PPtrans.out.print( "> " ); PPtrans.out.print( className ); } } // Output arguments declared size = giv.get_argClassList().size(); // Arguments are much simpler for( int i = 0; i < size; i++ ) { Ident variableName = (Ident)giv.get_argVariableList(). elementAt( i ); Ident className = (Ident)giv.get_argClassList(). elementAt( i ); PPtrans.out.print( " <" ); PPtrans.out.print( variableName ); PPtrans.out.print( "> " ); PPtrans.out.print( className ); } PPtrans.out.println("."); @) } // A simple class used to keep a list for targets. It is used as a visitor // from the InTo.getTargetList() traversal. It gathers information on // what is after the "To" in a traversal. TargetVectorList { before InSpecificClassName (@ this.addElement( host.get_className().get_name() ); @) before InGlobalClassName (@ this.addElement( new Ident( "*" ) ); @) } // InTo. This is a mini-hub. From here, all SpecificClassNames and // GlobalClassNames are related to this InTo. That information is // gathered in the getTargetList traversal and added to a TargetVectorList InTo { traversal getTargetList( TargetVectorList target ){ to { InSpecificClassName, InGlobalClassName }; } } // GeneralInformationVisitor. This is on BIG visitor. It stores all // sorts of information about the propagation pattern, include return // variables, Argument lists, Transportation Variables, Initialization // Code... etc... GeneralInformationVisitor{ // Information from Transportation Variable before -> InSpecificClassName,tran,* (@ classList.addElement( ((InSpecificClassName)source). get_className(). get_name() ); variableList.addElement( ((InVariable)dest).get_name() ); @) // Information from arguments before -> InArg,tran,* (@ argClassList.addElement( ((InArg)source). get_className(). get_name() ); argVariableList.addElement( ((InVariable)dest).get_name() ); @) // Get the return type before InReturnTypeName (@ this.set_type( new ReturnValueType( new Ident( host.get_name() ) ) ); @) // Get the Class Name the traversal is located in before InTraversalClassName (@ this.set_className( new ClassName( host.get_name() ) ); @) // Get the name of the traversal before InTraversalName (@ this.set_traversalName( new TraversalName( host.get_name() ) ); @) // Get the target of the traversal before InTo (@ host.getTargetList( this.get_targets() ); @) // Get Initialization Code before InInitializeText (@ this.set_initialize( new InitializationText( host.get_code())); @) } // This is where a "through" command is implemented within a traversal. // From there, we gather information on the edges and classes that we // need to go through. // // There are two traversals: // // getEdges( DirectiveClasses dc ) // getClasses( DirectiveClasses dc ) // // getEdges gathers information about the edges we need to go through, and // puts it into a DirectiveClasses list. This list is processed later. // // getClasses gathers information about the classes we need to go through, and // puts it into a DirectiveClasses list. This list is processed later. InThroughDirective { traversal getEdges( DirectiveClasses dc){ bypassing InClassSpec to { InPartEdge, InSuperEdge, InSubEdge, InGlobalClassName, InPartName, InJavaTypeName }; } traversal getClasses( DirectiveClasses dc ) { bypassing InEdgeSpec to { InGlobalClassName, InJavaTypeName }; } } // This is where a "bypassing" command is implemented within a traversal. // From here, we gather information on edges and classes that we need to // bypass. // // There are two traversals: // // getEdges( DirectiveClasses dc ) // getClasses( DirectiveClasses dc ) // // getEdges gathers information about the edges we need to bypass, and // puts it into a DirectiveClasses list. This list is processed later. // // getClasses gathers information about the classes we need to bypass, and // puts it into a DirectiveClasses list. This list is processed later. // InBypassDirective { traversal getEdges( DirectiveClasses dc ){ bypassing InClassSpec to { InPartEdge, InSuperEdge, InSubEdge, InGlobalClassName, InPartName, InJavaTypeName }; } traversal getClasses( DirectiveClasses dc ) { bypassing InEdgeSpec to { InGlobalClassName, InJavaTypeName }; } } // Directive classes is a subclass of Vector. We add wrappers to it // and the PathDirectiveVisitor sends them into traversal to gather // information about the through and bypass directives. All the wrappers // do is add information to itself. DirectiveClasses { before InPartName (@ this.addElement( host.get_name() ); @) before InPartEdge(@ this.addElement( new Ident( "->" ) ); @) before InSuperEdge(@ this.addElement( new Ident( ":>" ) ); @) before InSubEdge(@ this.addElement( new Ident( "=>" ) ); @) before InGlobalClassName(@ this.addElement( new Ident( "*" ) ); @) before InJavaTypeName (@ this.addElement( host.get_name() ); @) } // PathDirectiveVisitor is a visitor that is used to gather information // about all the through and bypass commands in a propagation pattern. PathDirectiveVisitor { // Get the through's before InThroughDirective (@ DirectiveClasses dc = new DirectiveClasses(); directives.addElement( new Ident( "through" ) ); host.getEdges( dc ); this.get_dedgelist().addElement( dc ); dc = new DirectiveClasses(); host.getClasses( dc ); this.get_dclasslist().addElement( dc ); @) //Get the bypasses before InBypassDirective (@ DirectiveClasses dc = new DirectiveClasses(); directives.addElement( new Ident( "bypassing" ) ); host.getEdges( dc ); this.get_dedgelist().addElement( dc ); dc = new DirectiveClasses(); host.getClasses( dc ); this.get_dclasslist().addElement( dc ); @) } // InitializationVisitor is a simple visitor that gathers the list of // transportation variables that we need to make sure we initialize in // our translation. InitializationVisitor { before InSpecificClassName (@ if( classList.indexOf( host.get_className().get_name() ) == -1) { if( host.get_tran() != null ) { classList.addElement( host.get_className().get_name()); variableList.addElement( host.get_tran().get_name() ); } } @) } // WrapperClassList is a simple sub-class of Vector that is used to // keep a list of classes that is used in a wrapper. WrapperClassList { before InGlobalClassName (@ this.addElement( new Ident( "*" ) ); @) before InJavaTypeName (@ this.addElement( host.get_name() ); @) before InPartName (@ this.addElement( host.get_name() ); @) } // WrapperPrefix contains a simple Ident that contains wether or not // a wrapper is a "before" or "after" wrapper. WrapperPrefix { before InBefore (@ this.set_prefix( new Ident( "before" ) ); @) before InAfter (@ this.set_prefix( new Ident( "after" ) ); @) } // WrapperCodeList is a simple class that contains the Java Code located // in a wrapper. WrapperCodeList{ before InJavaCode (@ this.addElement( host.get_code().toString() ); @) } // WrapperEdgeType is a simple class that contains an Ident which indicates // what type of edge wrapper we are dealing with. WrapperEdgeType{ before InPartEdge (@ this.addElement( new Ident( "->" ) ); @) before InSubEdge (@ this.addElement( new Ident( "=>" ) ); @) before InSuperEdge (@ this.addElement( new Ident( ":>" ) ); @) } // InWrapper. This is a major hub for traversals. Many traversal // spawn from this point, taking parts of the GeneralInformationVisitor // with them. Kinda like the Mother-Ship in Independence Day sending out // thousands of little ships for recon (hopefully without explosions). // // This class contains 5 traversals: // // getWrapperClassNames. This gets all the Class Names located in a class // wrapper. // // getWrapperEdgeNames. This get all the Class Names located in an edge // wrapper. // // getJavaCode. This gets the java code located in a wrapper. // // getWrapperPrefix. This get the "before" and "after" wrapper identifiers. // // getWrapperEdgeTypes. This gets the Edge Type of an edge-wrapper (=>,->,:>). // InWrapper { // Get the ClassNames not in an edge wrapper traversal getWrapperClassNames( WrapperClassList cl ){ bypassing InEdgeSpec to { InJavaTypeName, InGlobalClassName}; } // Get the ClassNames in an edge wrapper traversal getWrapperEdgeNames( WrapperClassList cl ){ bypassing InClassSpec to { InJavaTypeName, InPartName, InGlobalClassName }; } // Get the Java Code traversal getJavaCode( WrapperCodeList cl ){ to InJavaCode; } // Get the Wrapper Prefixes traversal getWrapperPrefix( WrapperPrefix wp ){ to {InBefore, InAfter}; } // Get Edge Wrapper Types traversal getWrapperEdgeTypes( WrapperEdgeType wt ){ to {InPartEdge, InSuperEdge, InSubEdge}; } } // EWrapInfoVisitor. Edge-Wrapper-Information-Visitor. This Visitor // gathers all the information about the edge wrappers in a propagation // pattern. EWrapInfoVis { before InWrapper (@ this.set_classList( new WrapperClassList() ); host.getWrapperEdgeNames( classList ); host.getWrapperEdgeTypes( edgeType ); // If we found edges, add them. if( edgeType.size() > 0 ) { edgeTypeList.addElement( edgeType ); this.set_edgeType( new WrapperEdgeType() ); } host.getJavaCode( codeList ); @) after InWrapper (@ if( this.get_classList().size() > 0) { host.getWrapperPrefix( wrapperPrefix ); wrapperPrefixList.addElement( wrapperPrefix.get_prefix() ); classListList.addElement( classList ); } @) } // CWrapInfoVis. Class-Wrapper-Information-Visitor. This Visitor controls // all the information gathers from class wrappers. CWrapInfoVis { before InWrapper (@ this.set_classList( new WrapperClassList() ); host.getWrapperClassNames( classList ); host.getJavaCode( codeList ); @) after InWrapper (@ if( this.get_classList().size() > 0 ) { host.getWrapperPrefix( this.get_wrapperPrefix() ); wrapperPrefixList.addElement( wrapperPrefix.get_prefix() ); classListList.addElement( classList ); } @) } // OutTraversal. This class is the main class of out output translation. // It contains one visitor that output the translated code. OutTraversal{ traversal translate( PrintingVisitor pv ){ to *; } } // PrintingVisitor. This is the BIGGEST and HARRIEST visitor. This visitor // processes the information gathered and output lot's o' translated code. // Unfortunately, it isn't the cleanest code in the translator. PrintingVisitor{ (@ // outputPrefix( int ) // This outputs the "before" or "after" in a wrapper. void outputPrefix( int position ) { int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); if ( position < csize ) { PPtrans.out.print( (Ident)cwiv.get_wrapperPrefixList(). elementAt( position ) ); } else { PPtrans.out.print( (Ident)ewiv.get_wrapperPrefixList(). elementAt( position - csize )); } PPtrans.out.print( " " ); } @) (@ // getClassList( int ) // // this procedure returns the appropriate class list given the current // position. WrapperClassList getClassList( int position ) { int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); if ( position < csize ) { return (WrapperClassList)cwiv.get_classListList(). elementAt( position ); } else { return (WrapperClassList)ewiv.get_classListList(). elementAt( position - csize ); } } @) (@ // outputClassWrapperInitializations( position, offset ) // // This procedure outputs the initialzations of transporation variables. In // user-defined wrappers. void outputClassWrapperInitializations( int position, int offset ) { WrapperClassList classList = getClassList( position ); Ident className = (Ident)classList.elementAt( offset ); int index = giv.get_classList().indexOf( className ); if( index != -1 ) { printTabs(); PPtrans.out.print( getTabs() + "this.set_" ); PPtrans.out.print( (Ident)giv.get_variableList(). elementAt( index ) ); PPtrans.out.print( "( host );" ); // it has been initialized. Let's remove it from // the initialization list. int initPos = iiv.get_classList().indexOf( className ); if( initPos != -1 ) { iiv.get_classList().removeElementAt( initPos ); iiv.get_variableList().removeElementAt(initPos); } } } @) (@ // outputTransportationInitializations( int ). Controls the output // of wrapper transportation variable initialization in user-defined // wrappers. void outputTransportationInitializations( int position, int offset ) { int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); if ( position < csize ) { outputClassWrapperInitializations( position, offset ); } } @) (@ // outputEdgeType( int, int ). Outputs a given edge type, given the location // of the edge in a list. void outputEdgeType( int position, int edgeNumber ) { int csize = cwiv.get_wrapperPrefixList().size(); PPtrans.out.print( " " ); WrapperEdgeType typeList = (WrapperEdgeType)ewiv.get_edgeTypeList(). elementAt( position - csize ); PPtrans.out.print( typeList.elementAt( edgeNumber ) ); PPtrans.out.print( " " ); } @) (@ // outputClasses( int ) // // outputs a list of Class Wrapper Classes. void outputClasses( int position ) { WrapperClassList classList = getClassList( position ); int totalSize = classList.size(); if ( totalSize > 1 ) { PPtrans.out.print( "{" ); // Print out the first part of our element PPtrans.out.print( classList.elementAt( 0 ) ); // Now we out the rest of the list for( int k = 1; k < totalSize; k++ ) { PPtrans.out.print( "," ); PPtrans.out.print( classList.elementAt( k ) ); } PPtrans.out.print( "}" ); } else { PPtrans.out.print( classList.elementAt( 0 ) ); } } @) (@ // outputClass( int, int ) // // outputs a class void outputClass( int position, int offset ) { WrapperClassList classList = getClassList( position ); int totalSize = classList.size(); // Print out the first part of our element PPtrans.out.print( classList.elementAt( offset ) ); PPtrans.out.println( "(" + "@" ); } @) (@ // outputEdge( WrapperClassList, int ) // // outputs an edge wrapper, given it's position in a list. void outputEdge( WrapperClassList classList, int startingPos ) { // Print out the first part of our element PPtrans.out.print( classList.elementAt( startingPos ) ); // print out the rest of our element for( int i = startingPos + 1; i < (startingPos + 3); i++ ) { PPtrans.out.print( "," ); PPtrans.out.print( classList.elementAt( i ) ); } } @) (@ // outputEdges( int ). Output a the list of wrapper edges. void outputEdges( int position ) { WrapperClassList classList = getClassList( position ); int totalSize = classList.size(); if ( totalSize > 3 ) { PPtrans.out.print( "{" ); outputEdgeType( position, 0 ); outputEdge( classList, 0 ); for( int k = 3; k < totalSize; k = k + 3 ) { PPtrans.out.print( "," ); outputEdgeType( position, k/3 ); outputEdge( classList, k ); } PPtrans.out.print( "}" ); } else { outputEdgeType( position, 0 ); outputEdge( classList, 0 ); } } @) (@ // outputClassList( int, int ) // // A generic procedure that output either Edges or Classes given a position // and elementSize. A class wrapper would have an elementSize of 1. A // edge wrapper has an element size of 3. void outputClassList( int position, int elementSize ) { if( elementSize == 1 ) { outputClasses( position ); } else { outputEdges( position ); } PPtrans.out.println( "(" + "@" ); } @) (@ // outputInitialization( int ) // // output all the initialization for a given wrapper. void outputInitialization( int position, int offset ) { PPtrans.out.println(); outputTransportationInitializations( position, offset ); PPtrans.out.println(); PPtrans.out.print( "\n" + getTabs() + "// Initialize" ); PPtrans.out.println( " Transportation variables" ); Ident returnType = giv.get_type().get_type(); if( !giv.get_type().get_type().equals( new Ident( "void" ) ) ){ PPtrans.out.print( getTabs() + returnType + " return_val" + " = " ); PPtrans.out.println( "this.get_return_val();" ); } outputArgumentsInitialization(); outputPrelude(); PPtrans.out.println(); } @) (@ // outputArgumentInitialization() // // output all the argument initializations. void outputArgumentsInitialization() { // Output arguments int size = giv.get_argClassList().size(); for( int i = 0; i < size; i++ ) { Ident classes = (Ident)giv.get_argClassList().elementAt( i ); Ident name = (Ident)giv.get_argVariableList().elementAt( i ); PPtrans.out.print( getTabs() + classes ); PPtrans.out.print( " " + name ); PPtrans.out.println( " = " + "this.get_" + name +"();"); } } @) (@ // outputPrelude(). Outputs all initialization code for transportation // variables in User defined wrappers. void outputPrelude() { // Output Transportation int size = giv.get_classList().size(); for( int i = 0; i < size; i++ ) { Ident classes = (Ident)giv.get_classList().elementAt( i ); Ident name = (Ident)giv.get_variableList().elementAt( i ); // This is necessary because we may have more than one variable // pointing to the same class. //------------------------------------------------------------- // Find the first reference to the class stored in "classes" int indexOfName = giv.get_classList().indexOf( classes ); // Get it's associated variable name, and use that in the getting. Ident variableName = (Ident)giv.get_variableList().elementAt(indexOfName); //------------------------------------------------------------- PPtrans.out.print( getTabs() + classes ); PPtrans.out.print( " " + name ); PPtrans.out.println( " = " + "this.get_" + variableName +"();"); } } @) (@ // outputTransInitWithoutCode(). Outputs all transportation initializers // that are necessary. void outputTransInitWithoutCode() { int size = iiv.get_classList().size(); PPtrans.out.println(); for( int count = 0; count < size; count++ ) { PPtrans.out.print( "before "); PPtrans.out.print( (Ident)iiv.get_classList().elementAt( count ) ); PPtrans.out.println( "(" + "@" ); Inc(); PPtrans.out.print( getTabs() + "this.set_" ); PPtrans.out.print( (Ident)iiv.get_variableList().elementAt(count)); PPtrans.out.println( "( host );" ); Dec(); PPtrans.out.println( "@" + ")" ); } } @) (@ // outCode( int ). Outputs the java code located in a wrapper. void outCode( int position ) { int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); if ( position < csize ) { PPtrans.out.println( (String)cwiv.get_codeList().elementAt( position )); } else { PPtrans.out.println( (String)ewiv.get_codeList().elementAt( position-csize )); } } @) (@ // outputPostlude( ). Outputs all the setters necessary to keep the // initializers up to date. void outputPostlude( ) { int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); // Reset the argument and transportation variables. // // this is necessary to make sure terminal classes of type int, float, // etc... are correctly set. PPtrans.out.println(); if( !giv.get_type().get_type().equals( new Ident( "void" ) ) ){ PPtrans.out.println( getTabs() + "this.set_return_val( return_val );" ); } // output transportation variable setting int size = giv.get_classList().size(); for( int i = 0; i < size; i++ ) { Ident name = (Ident)giv.get_variableList().elementAt( i ); Ident classes = (Ident)giv.get_classList().elementAt( i ); // Find the first mention of class "classes" in our class list int indexOfName = giv.get_classList().indexOf( classes ); // Get it's associated variable name, and use that in the setting. Ident variableName = (Ident)giv.get_variableList().elementAt(indexOfName); PPtrans.out.println( getTabs() + "this.set_" + variableName + "(" + name + ");"); } // output argument setting size = giv.get_argClassList().size(); for( int i = 0; i < size; i++ ) { Ident name = (Ident)giv.get_argVariableList().elementAt( i ); PPtrans.out.println( getTabs() + "this.set_" + name +"(" + name + ");"); } PPtrans.out.println(); PPtrans.out.println( "@" + ")" ); } @) (@ // Inc(). For pretty printing. Increase tabs count. void Inc( ) { this.set_tcount( new TabCount( new Integer( tcount.get_count().intValue() + 1 ))); } // Dec(). For pretty printing. Decreases tab count. void Dec( ) { this.set_tcount( new TabCount( new Integer( tcount.get_count().intValue() - 1 ))); } // getTabs(). For pretty printing. Returns a list of tabs. String getTabs( ) { String str = new String(); for( int i = 0; i < tcount.get_count().intValue(); i++ ) { str = str + "\t"; } return str; } // printTabs(). For pretty printing. Outputs tabs. void printTabs( ) { for( int i = 0; i < tcount.get_count().intValue(); i++ ) { PPtrans.out.print( "\t" ); } } @) // WRAPPERS // These are the variety of wrappers I use to output the translation. // I will not go into detail on all of them. // X{ before OutClass (@ PPtrans.out.println( giv.get_className().get_name() + "{" ); @) // (@ Ident test before OutTraverseCode (@ PPtrans.out.print( "(" + "@ " + giv.get_type(). get_type() + " " + giv. get_traversalName().get_name() ); @) // @) after OutTraverseCode (@ PPtrans.out.println( "@" + ")" ); @) // ( int i, int k ) before OutTraversalArgs (@ PPtrans.out.print( "(" ); int size = giv.get_argClassList().size(); if( size > 0 ) { PPtrans.out.print( giv. get_argClassList().elementAt( 0 ) ); PPtrans.out.print( " " + giv. get_argVariableList().elementAt( 0 ) ); for( int i = 1; i < size; i++ ) { PPtrans.out.print( "," + giv. get_argClassList().elementAt( i ) ); PPtrans.out.print( " " + giv. get_argVariableList().elementAt( i ) ); } } PPtrans.out.print(")"); @) after OutTransportationInit (@ Dec(); @) // { // TraversalVisitortest traversal = new TraversalVisitortest(); // traversal.set_return_val( new Ident( "test" ) ); // // traversal.set_i( i ); // traversal.set_k( k ); before OutTraversalInit (@ PPtrans.out.println( "{" ); Inc(); Ident name = giv.get_traversalName().get_name(); // Declare Traversal Visitor PPtrans.out.print( getTabs() + "TraversalVisitor" ); PPtrans.out.print( name ); PPtrans.out.print( " traversal" ); PPtrans.out.print( " = new TraversalVisitor" ); PPtrans.out.print( name ); PPtrans.out.println( "();" ); // Initialize return value, if one is specified if( (!giv.get_type().get_type().equals(new Ident( "void" ))) && (giv.get_initialize() != null) ) { PPtrans.out.println(); PPtrans.out.println( "// initialization code for return_val" ); printTabs(); PPtrans.out.print( "traversal.set_return_val( " ); PPtrans.out.print( giv.get_initialize().get_code() ); PPtrans.out.println( " );" ); } // Add passed in values int size = giv.get_argClassList().size(); for( int i = 1; i <= size; i++ ) { Ident varName = (Ident)giv.get_argVariableList() .elementAt( i-1 ); PPtrans.out.print( getTabs() + "traversal."); PPtrans.out.print( "set_" ); PPtrans.out.print( varName ); PPtrans.out.print( "( " ); PPtrans.out.print( varName ); PPtrans.out.println( " );" ); } @) after OutTraversalInit (@ Dec(); @) // this.traversePPtest( traversal ); // // return traversal.get_return_val(); // } before OutBody (@ Inc(); Ident name = giv.get_traversalName().get_name(); PPtrans.out.print( getTabs() + "this.traversePP" ); PPtrans.out.print( name + "( traversal );" ); if( !giv.get_type().get_type().equals( new Ident( "void" ) ) ) { PPtrans.out.println(); printTabs(); PPtrans.out.println( "return traversal.get_return_val();" ); } PPtrans.out.println( "}" ); @) after OutBody (@ Dec(); @) // traversal traversePPtest( TraversalVisitortest tv ){ // through{ A,B } // to C; // } before OutTraversalDecl (@ Inc(); Ident name = giv.get_traversalName().get_name(); // output declaration PPtrans.out.print( getTabs() + "traversal traversePP" ); PPtrans.out.print( name + "(" ); PPtrans.out.print( "TraversalVisitor" ); PPtrans.out.print( name ); PPtrans.out.println( " tv ){" ); Inc(); // Output through, and bypassing path directives int size = pdv.get_directives().size(); for( int count = 0; count < size; count++ ) { PPtrans.out.print( getTabs() + (Ident)pdv.get_directives(). elementAt( count ) ); int dclassSize = pdv.get_dclasslist().size(); int dedgeSize = pdv.get_dedgelist().size(); int totalSize = dclassSize + dedgeSize; if( totalSize > 1 ) { PPtrans.out.print( "{ " ); } // Output Edges DirectiveClasses edgeClasses = (DirectiveClasses)pdv. get_dedgelist(). elementAt( count ); for( int edgeCount = 0; edgeCount < edgeClasses.size(); edgeCount+=4 ) { PPtrans.out.print( (Ident)edgeClasses.elementAt( edgeCount ) ); PPtrans.out.print( " " ); PPtrans.out.print( (Ident)edgeClasses.elementAt(edgeCount+1)); PPtrans.out.print( "," ); PPtrans.out.print( (Ident)edgeClasses.elementAt(edgeCount+2)); PPtrans.out.print( "," ); PPtrans.out.print( (Ident)edgeClasses.elementAt(edgeCount+3)); if( (edgeCount + 4) < edgeClasses.size() ) { PPtrans.out.print( "," ); } } // Output Classes DirectiveClasses classes = (DirectiveClasses)pdv. get_dclasslist(). elementAt( count ); if( (edgeClasses.size() > 0) && (classes.size() > 0) ) { PPtrans.out.print( "," ); } for( int classCount = 0; classCount < classes.size(); classCount++ ) { PPtrans.out.print( (Ident)classes.elementAt( classCount )); if( (classCount + 1) < classes.size() ) { PPtrans.out.print( "," ); } } if( totalSize > 1 ) { PPtrans.out.print( " }" ); } PPtrans.out.println(); } // Output "to" directives PPtrans.out.print( getTabs() + "to " ); size = giv.get_targets().size(); if ( size > 1 ) { PPtrans.out.print( "{" ); PPtrans.out.print( (Ident)giv.get_targets().elementAt(0) ); for( int i = 1; i < size; i++ ) { PPtrans.out.print( "," + (Ident)giv.get_targets(). elementAt(i)); } PPtrans.out.println( "};" ); } else { PPtrans.out.print( (Ident)giv. get_targets().elementAt(0) ); PPtrans.out.println( ";" ); } Dec(); PPtrans.out.println( getTabs() + "}" ); @) after OutTraversalDecl (@ Dec(); @) // } after OutClass (@ PPtrans.out.println( "}" ); @) // TraversalVisitortest { before OutVisitor (@ Ident name = giv.get_traversalName().get_name(); PPtrans.out.println( "TraversalVisitor" + name + " {" ); PPtrans.out.println(); Inc(); @) // } after OutVisitor (@ Dec(); PPtrans.out.println( "}" ); @) // before A{ // // int i = this.get_i(); // int k = this.get_k(); // // System.out.println( i ); // i++; // // this.set_i( i ); // this.set_k( k ); // } before OutWrappers (@ int csize = cwiv.get_wrapperPrefixList().size(); int esize = ewiv.get_wrapperPrefixList().size(); int elementSize = 0; for( int position = 0; position < (csize + esize); position++ ) { if( position < csize ) elementSize = 1; else elementSize = 3; // outputClassList( position, elementSize ); WrapperClassList classList = getClassList( position ); int classListSize = classList.size(); // we split up call definitions so we can properly initialize // transportation variables if( position < csize ) { for( int count = 0; count < classListSize; count++ ) { outputPrefix( position ); outputClass( position, count ); outputInitialization( position, count ); outCode( position ); outputPostlude(); } } else { // We are in an edge list, we can now print everything // out. outputPrefix( position ); outputClassList( position, elementSize ); // outputInitialization for edge wrappers doesn't do // anything with the offset, se we just pass in a zero. outputInitialization( position, 0 ); outCode( position ); outputPostlude(); } } outputTransInitWithoutCode(); @) } // PPtrans. Our mainline. PPtrans { (@ public static PrintStream out; public static void main(String args[]) throws Exception { File ppfile=null; String cdname=null; String ppname=null; InTraversalPP tpp=null; if (args.length < 2){ System.out.print( "You must include CD Filename" ); System.out.print( " and PP Filenames on the command line"); System.out.println( "Do not include their extensions (cd or pp)."); System.exit(1); } else cdname = new String(args[0]); for (int arg = 1; arg < args.length; arg++) { ppname = new String(args[arg]); ppfile= new File(ppname + ".pp"); try { tpp = InTraversalPP.parse( new FileInputStream(ppfile)); } catch(FileNotFoundException e) { System.out.println( "Filename(s) not found."); System.out.print( "Do not include their extensions" ); System.out.println( "(cd or pp) on CL."); System.exit(1); } tpp.translate(cdname, ppname); } } @) }