| |
| /* |
| * 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; |
| } |
| |