blob: 294925ee15dc29b8c65b28a0042dd41eb1a02ab2 [file] [log] [blame]
/*
* 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;
}