📄 smccgenerator.java
字号:
//// The contents of this file are subject to the Mozilla Public// License Version 1.1 (the "License"); you may not use this file// except in compliance with the License. You may obtain a copy// of the License at http://www.mozilla.org/MPL///// Software distributed under the License is distributed on an// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or// implied. See the License for the specific language governing// rights and limitations under the License.//// The Original Code is State Machine Compiler (SMC).//// The Initial Developer of the Original Code is Charles W. Rapp.// Portions created by Charles W. Rapp are// Copyright (C) 2005. Charles W. Rapp.// All Rights Reserved.//// Contributor(s):// Eitan Suez contributed examples/Ant.// (Name withheld) contributed the C# code generation and// examples/C#.// Francois Perrad contributed the Python code generation and// examples/Python.// Chris Liscio contributed the Objective-C code generation// and examples/ObjC.//// RCS ID// $Id: SmcCGenerator.java,v 1.15 2008/03/21 14:03:16 fperrad Exp $//// CHANGE LOG// (See the bottom of this file.)//package net.sf.smc;import java.io.PrintStream;import java.io.StringWriter;import java.util.Iterator;import java.util.List;/** * Visits the abstract syntax tree emitting C++ code. * @see SmcElement * @see SmcCodeGenerator * @see SmcVisitor * * @author Francois Perrad */public final class SmcCGenerator extends SmcCodeGenerator{//---------------------------------------------------------------// Member methods// public SmcCGenerator(String srcfileBase) { super (srcfileBase, "{0}{1}_sm.{2}", "c"); } // end of SmcCGenerator(String) // This method generates the following code: // // %{ %} raw source code - if any // // #include <%include header file> // #include "<context>_sm.h" // (If the -headerd option is used, then this is generated: // #include "<header dir>/<context>_sm.h") // public void visit(SmcFSM fsm) { String srcDirectory = Smc.outputDirectory(); String headerDirectory = Smc.headerDirectory(); String packageName = fsm.getPackage(); String rawSource = fsm.getSource(); String context = fsm.getContext(); String mapName; String startStateName = fsm.getStartState(); List<SmcTransition> transList; String separator; List<SmcParameter> params; String declaration; String cState; int packageDepth = 0; int index; _source.println("/*"); _source.println(" * DO NOT EDIT."); _source.println(" * generated by smc (http://smc.sourceforge.net/)"); _source.print(" * from file : "); _source.print(_srcfileBase); _source.println(".sm"); _source.println(" */"); _source.println(); // If a package has been specified, if (packageName != null && packageName.length() > 0) { context = packageName + "_" + context; startStateName = packageName + "_" + startStateName; } // Dump out the raw source code, if any. if (rawSource != null && rawSource.length() > 0) { _source.println(rawSource); _source.println(); } _source.println("#include <assert.h>"); // Generate #includes. for (String include: fsm.getIncludes()) { _source.print("#include "); _source.println(include); } // Include the context file last. // Is the header file included in a different directory // than the source file? _source.print("#include \""); if ((srcDirectory == null && headerDirectory != null) || (srcDirectory != null && headerDirectory != null && srcDirectory.equals(headerDirectory) == false)) { // They are in different directories. Prepend the // header directory to the file name. _source.print(headerDirectory); } // Else they are in the same directory. else if (srcDirectory != null) { _source.print(srcDirectory); } _source.print(_srcfileBase); _source.println("_sm.h\""); // Print out the default definitions for all the // transitions. First, get the transitions list. transList = fsm.getTransitions(); _source.println(); _source.println("#define getOwner(fsm) \\"); _source.println(" (fsm)->_owner"); _source.println(); _source.println("#define POPULATE_STATE(state) \\"); if (fsm.hasEntryActions() == true) { _source.println(" state##_Entry, \\"); } if (fsm.hasExitActions() == true) { _source.println(" state##_Exit, \\"); } for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.print(" state##_"); _source.print(trans.getName()); _source.println(", \\"); } } _source.println(" state##_Default"); _source.println(); if (fsm.hasEntryActions() == true) { _source.println("#define ENTRY_STATE(state) \\"); _source.println(" if ((state)->Entry != NULL) { \\"); _source.println(" (state)->Entry(fsm); \\"); _source.println(" }"); } else { _source.println("#define ENTRY_STATE(state)"); } _source.println(); if (fsm.hasExitActions() == true) { _source.println("#define EXIT_STATE(state) \\"); _source.println(" if ((state)->Exit != NULL) { \\"); _source.println(" (state)->Exit(fsm); \\"); _source.println(" }"); } else { _source.println("#define EXIT_STATE(state)"); } // Output the default transition definitions. for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.println(); _source.print("static void "); _source.print(context); _source.print("State_"); _source.print(trans.getName()); _source.print("(struct "); _source.print(context); _source.print("Context *fsm"); params = trans.getParameters(); for (SmcParameter param: params) { _source.print(", "); param.accept(this); } _source.println(")"); _source.println("{"); _source.println( " getState(fsm)->Default(fsm);"); _source.println("}"); } } _source.println(); _source.print("static void "); _source.print(context); _source.print("State_Default(struct "); _source.print(context); _source.println("Context *fsm)"); _source.println("{"); // Print the transition out to the verbose log. if (Smc.isDebug() == true) { _source.println(" if (getDebugFlag(fsm) != 0) {"); // The TRACE macro. _source.print(" TRACE("); _source.print("\"TRANSITION : %s.%s\\n\\r\", "); _source.println( "getName(getState(fsm)), getTransition(fsm));"); _source.println(" }"); } _source.println(" State_Default(fsm);"); _source.println("}"); // Have each map print out its source code now. for (SmcMap map: fsm.getMaps()) { mapName = map.getName(); if (packageName != null && packageName.length() > 0) { mapName = packageName + "_" + mapName; } _source.println(); for (SmcState state: map.getStates()) { for (SmcTransition trans: transList) { if (trans.getName().equals( "Default") == false) { _source.print("#define "); _source.print(mapName); _source.print("_"); _source.print(state.getInstanceName()); _source.print("_"); _source.print(trans.getName()); _source.print(" "); _source.print(context); _source.print("State_"); _source.println(trans.getName()); } } _source.print("#define "); _source.print(mapName); _source.print("_"); _source.print(state.getInstanceName()); _source.print("_Default "); _source.print(context); _source.println("State_Default"); _source.print("#define "); _source.print(mapName); _source.print("_"); _source.print(state.getInstanceName()); _source.println("_Entry NULL"); _source.print("#define "); _source.print(mapName); _source.print("_"); _source.print(state.getInstanceName()); _source.println("_Exit NULL"); } for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.print("#define "); _source.print(mapName); _source.print("_DefaultState_"); _source.print(trans.getName()); _source.print(" "); _source.print(context); _source.print("State_"); _source.println(trans.getName()); } } map.accept(this); } // The state name "map::state" must be changed to // "map_state". if ((index = startStateName.indexOf("::")) >= 0) { cState = startStateName.substring(0, index) + "_" + startStateName.substring(index + 2); } else { cState = startStateName; } _source.println(); _source.print("void "); _source.print(context); _source.print("Context_Init"); _source.print("(struct "); _source.print(context); _source.print("Context* fsm, struct "); _source.print(context); _source.println("* owner)"); _source.println("{"); _source.println(" FSM_INIT(fsm);"); _source.println(" fsm->_owner = owner;"); _source.print(" setState(fsm, &"); _source.print(cState); _source.println(");"); _source.print(" ENTRY_STATE(&"); _source.print(cState); _source.println(");"); _source.println("}"); // Generate the context class. // Generate a method for every transition in every map // *except* the default transition. for (SmcTransition trans: transList) { if (trans.getName().equals("Default") == false) { _source.println(); _source.print("void "); _source.print(context); _source.print("Context_"); _source.print(trans.getName()); _source.print("(struct "); _source.print(context); _source.print("Context* fsm"); params = trans.getParameters(); for (SmcParameter param: params) { _source.print(", "); _source.print(param.getType()); _source.print(" "); _source.print(param.getName()); } _source.println(")"); _source.println("{"); _source.print(" const struct "); _source.print(context); _source.println("State* state = getState(fsm);"); _source.println(); _source.println(" assert(state != NULL);"); _source.print(" setTransition(fsm, \""); _source.print(trans.getName()); _source.println("\");"); _source.print(" state->"); _source.print(trans.getName()); _source.print("(fsm"); for (SmcParameter param: params) { _source.print(", "); _source.print(param.getName()); } _source.println(");"); _source.println(" setTransition(fsm, NULL);"); _source.println("}"); } } return; } // end of visit(SmcFSM) public void visit(SmcMap map) { String packageName = map.getFSM().getPackage(); String context = map.getFSM().getContext(); String mapName = map.getName(); String transName; String stateName; // If a package has been specified, if (packageName != null && packageName.length() > 0) { context = packageName + "_" + context; mapName = packageName + "_" + mapName; } // Declare the user-defined default transitions first. if (map.hasDefaultState() == true) { SmcState defaultState = map.getDefaultState(); for (SmcTransition trans: defaultState.getTransitions()) { transName = trans.getName(); _source.println(); for (SmcState state: map.getStates()) { stateName = state.getInstanceName(); // Firstly, make sure the transition name // is not defined. _source.print("#undef "); _source.print(mapName); _source.print("_"); _source.print(stateName); _source.print("_"); _source.println(transName); // Secondly, define the transition name // to be a default transition alias. _source.print("#define "); _source.print(mapName); _source.print("_");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -