/* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * $Id$ * * */ #include "mem/slicc/main.hh" #include "mem/slicc/symbols/StateMachine.hh" #include "mem/slicc/generator/mif_gen.hh" #include "mem/slicc/generator/html_gen.hh" #include "mem/slicc/generator/fileio.hh" #include "mem/slicc/ast/DeclListAST.hh" #include "mem/slicc/symbols/Type.hh" #include "mem/slicc/symbols/SymbolTable.hh" #include "mem/slicc/symbols/Event.hh" #include "mem/slicc/symbols/State.hh" #include "mem/slicc/symbols/Action.hh" #include "mem/slicc/symbols/Transition.hh" // -- Main conversion functions void printDotty(const StateMachine& sm, ostream& out); void printTexTable(const StateMachine& sm, ostream& out); DeclListAST* g_decl_list_ptr; DeclListAST* parse(string filename); int main(int argc, char *argv[]) { cerr << "SLICC v0.3" << endl; if (argc < 5) { cerr << " Usage: generator.exec <code path> <html path> <ident> <html direction> files ... " << endl; exit(1); } // The path we should place the generated code string code_path(argv[1]); code_path += "/"; // The path we should place the generated html string html_path(argv[2]); html_path += "/"; string ident(argv[3]); string html_generate(argv[4]); Vector<DeclListAST*> decl_list_vec; // Parse cerr << "Parsing..." << endl; for(int i=5; i<argc; i++) { cerr << " " << argv[i] << endl; DeclListAST* decl_list_ptr = parse(argv[i]); decl_list_vec.insertAtBottom(decl_list_ptr); } // Find machines cerr << "Generator pass 1..." << endl; int size = decl_list_vec.size(); for(int i=0; i<size; i++) { DeclListAST* decl_list_ptr = decl_list_vec[i]; decl_list_ptr->findMachines(); } // Generate Code cerr << "Generator pass 2..." << endl; for(int i=0; i<size; i++) { DeclListAST* decl_list_ptr = decl_list_vec[i]; decl_list_ptr->generate(); delete decl_list_ptr; } // Generate C/C++ files cerr << "Writing C files..." << endl; { // Generate the name of the protocol ostringstream sstr; sstr << "// Auto generated C++ code started by "<<__FILE__<<":"<<__LINE__<<endl; sstr << endl; sstr << "#ifndef PROTOCOL_NAME_H" << endl; sstr << "#define PROTOCOL_NAME_H" << endl; sstr << endl; sstr << "const char CURRENT_PROTOCOL[] = \""; sstr << ident << "\";\n"; sstr << "#endif // PROTOCOL_NAME_H" << endl; conditionally_write_file(code_path + "/protocol_name.hh", sstr); } g_sym_table.writeCFiles(code_path); // Generate HTML files if (html_generate == "html") { cerr << "Writing HTML files..." << endl; g_sym_table.writeHTMLFiles(html_path); } else if (html_generate == "no_html") { cerr << "No HTML files generated" << endl; } else { cerr << "ERROR, unidentified html direction" << endl; } cerr << "Done..." << endl; // Generate MIF files cerr << "Writing MIF files..." << endl; g_sym_table.writeMIFFiles(html_path); cerr << "Done..." << endl; } /* if(!strcmp(argv[2], "parse")) { // Parse only } else if(!strcmp(argv[2], "state")) { printStateTableMIF(s, cout); } else if(!strcmp( argv[2], "event")) { printEventTableMIF(s, cout); } else if(!strcmp( argv[2], "action")) { printActionTableMIF(s, cout); } else if(!strcmp( argv[2], "transition")) { printTransitionTableMIF(s, cout); } else if(!strcmp( argv[2], "tbe")) { for(int i=0; i<s.numTypes(); i++) { if (s.getType(i).getIdent() == "TBE") { printTBETableMIF(s, s.getTypeFields(i), cout); } } } else if(!strcmp( argv[2], "dot")) { printDotty(s, cout); } else if(!strcmp( argv[2], "latex")) { printTexTable(s, cout); } else if (!strcmp( argv[2], "murphi")) { printMurphi(s, cout); } else if (!strcmp( argv[2], "html")) { printHTML(s); } else if(!strcmp( argv[2], "code")) { if (argc < 4) { cerr << "Error: Wrong number of command line parameters!" << endl; exit(1); } */ void printDotty(const StateMachine& sm, ostream& out) { out << "digraph " << sm.getIdent() << " {" << endl; for(int i=0; i<sm.numTransitions(); i++) { const Transition& t = sm.getTransition(i); // Don't print ignored transitions if ((t.getActionShorthands() != "--") && (t.getActionShorthands() != "z")) { // if (t.getStateShorthand() != t.getNextStateShorthand()) { out << " " << t.getStateShorthand() << " -> "; out << t.getNextStateShorthand() << "[label=\""; out << t.getEventShorthand() << "/" << t.getActionShorthands() << "\"]" << endl; } } out << "}" << endl; } void printTexTable(const StateMachine& sm, ostream& out) { const Transition* trans_ptr; int stateIndex, eventIndex; string actions; string nextState; out << "%& latex" << endl; out << "\\documentclass[12pt]{article}" << endl; out << "\\usepackage{graphics}" << endl; out << "\\begin{document}" << endl; // out << "{\\large" << endl; out << "\\begin{tabular}{|l||"; for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { out << "l"; } out << "|} \\hline" << endl; for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { out << " & \\rotatebox{90}{"; out << sm.getEvent(eventIndex).getShorthand(); out << "}"; } out << "\\\\ \\hline \\hline" << endl; for(stateIndex=0; stateIndex < sm.numStates(); stateIndex++) { out << sm.getState(stateIndex).getShorthand(); for(eventIndex=0; eventIndex < sm.numEvents(); eventIndex++) { out << " & "; trans_ptr = sm.getTransPtr(stateIndex, eventIndex); if (trans_ptr == NULL) { } else { actions = trans_ptr->getActionShorthands(); // FIXME: should compare index, not the string if (trans_ptr->getNextStateShorthand() != sm.getState(stateIndex).getShorthand() ) { nextState = trans_ptr->getNextStateShorthand(); } else { nextState = ""; } out << actions; if ((nextState.length() != 0) && (actions.length() != 0)) { out << "/"; } out << nextState; } } out << "\\\\" << endl; } out << "\\hline" << endl; out << "\\end{tabular}" << endl; // out << "}" << endl; out << "\\end{document}" << endl; }