📄 smcheadergenerator.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: SmcHeaderGenerator.java,v 1.9 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.util.Iterator;import java.util.List;import java.util.StringTokenizer;/** * Visits the abstract syntax tree emitting a C++ header file. * @see SmcElement * @see SmcVisitor * @see SmcCppGenerator * * @author <a href="mailto:rapp@acm.org">Charles Rapp</a> */public final class SmcHeaderGenerator extends SmcCodeGenerator{//---------------------------------------------------------------// Member methods// public SmcHeaderGenerator(String srcfileBase) { super (srcfileBase, "{0}{1}_sm.{2}", "h"); } // end of SmcHeaderGenerator(String) public void visit(SmcFSM fsm) { String srcfileCaps; String packageName = fsm.getPackage(); String context = fsm.getContext(); String mapName; List<SmcTransition> transList; String separator; List<SmcParameter> params; Iterator<SmcParameter> pit; int packageDepth = 0; // The first two lines in the header file should be: // // #ifndef _H_<source file name>_SM // #define _H_<source file name>_SM // // where the source file name is all in caps. // The last line is: // // #endif // // Make the file name upper case and replace // slashes with underscores. srcfileCaps = _srcfileBase.replace('\\', '_'); srcfileCaps = srcfileCaps.replace('/', '_'); srcfileCaps = srcfileCaps.toUpperCase(); _source.print("#ifndef _H_"); _source.print(srcfileCaps); _source.println("_SM"); _source.print("#define _H_"); _source.print(srcfileCaps); _source.println("_SM"); // If this application *is* using iostreams to output // debug messages, then define SMC_USES_IOSTREAMS. // Otherwise the user is responsible for providing a // TRACE macro to output the debug messages. if (Smc.isNoStreams() == false) { _source.println(); _source.println("#define SMC_USES_IOSTREAMS"); } // If this application is *not* using exceptions, then // define SMC_NO_EXCEPTIONS. if (Smc.isNoExceptions() == true) { _source.println(); _source.println("#define SMC_NO_EXCEPTIONS"); } // Include required standard .h files. _source.println(); _source.println("#include <statemap.h>"); _source.println(); // If a namespace was specified, then output that // namespace now. If the package name is "a::b::c", then // this must be converted to: // namespace a { // namespace b { // namespace c { // ... // } // } // } _indent = ""; if (packageName != null && packageName.length() > 0) { StringTokenizer tokenizer = new StringTokenizer(packageName, "::"); String token; while (tokenizer.hasMoreTokens() == true) { token = tokenizer.nextToken(); ++packageDepth; _source.print(_indent); _source.print("namespace "); _source.println(token); _source.print(_indent); _source.println("{"); _indent += " "; } } // Forward declare all the state classes in all the maps. _source.print(_indent); _source.println("// Forward declarations."); for (SmcMap map: fsm.getMaps()) { mapName = map.getName(); // class <map name>; _source.print(_indent); _source.print("class "); _source.print(mapName); _source.println(";"); // Iterate over the map's states. for (SmcState state: map.getStates()) { _source.print(_indent); _source.print("class "); _source.print(mapName); _source.print("_"); _source.print(state.getClassName()); _source.println(";"); } // Forward declare the default state as well. _source.print(_indent); _source.print("class "); _source.print(mapName); _source.println("_Default;"); } // Forward declare the state class and its // context as well. _source.print(_indent); _source.print("class "); _source.print(context); _source.println("State;"); _source.print(_indent); _source.print("class "); _source.print(context); _source.println("Context;"); // Forward declare the application class. _source.print(_indent); _source.print("class "); _source.print(context); _source.println(";"); // Do user-specified forward declarations now. for (String declaration: fsm.getDeclarations()) { _source.print(_indent); _source.print(declaration); // Add a semicolon if the user did not use one. if (declaration.endsWith(";") == false) { _source.print(";"); } _source.println(); } _source.println(); // Declare user's base state class. _source.print(_indent); _source.print("class "); _source.print(context); _source.println("State :"); _source.print(_indent); _source.println(" public statemap::State"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.println("public:"); _source.println(); // Constructor. _source.print(_indent); _source.print(" "); _source.print(context); _source.println("State(const char *name, int stateId)"); _source.print(_indent); _source.println(" : statemap::State(name, stateId)"); _source.print(_indent); _source.println(" {};"); _source.println(); // Add the default Entry() and Exit() definitions. _source.print(_indent); _source.print(" virtual void Entry("); _source.print(context); _source.println("Context&) {};"); _source.print(_indent); _source.print(" virtual void Exit("); _source.print(context); _source.println("Context&) {};"); _source.println(); // Print out the default definitions for all the // transitions. First, get the transitions list. transList = fsm.getTransitions(); // Output the global transition declarations. for (SmcTransition trans: transList) { // Don't output the default state here. if (trans.getName().equals("Default") == false) { _source.print(_indent); _source.print(" virtual void "); _source.print(trans.getName()); _source.print("("); _source.print(context); _source.print("Context& context"); params = trans.getParameters(); for (SmcParameter param: params) { _source.print(", "); param.accept(this); } _source.println(");"); } } // Declare the global Default transition. _source.println(); _source.print(_indent); _source.println("protected:"); _source.println(); _source.print(_indent); _source.print(" virtual void Default("); _source.print(context); _source.println("Context& context);"); // The base class has been defined. _source.print(_indent); _source.println("};"); _source.println(); // Generate the map classes. The maps will, in turn, // generate the state classes. for (SmcMap map: fsm.getMaps()) { map.accept(this); } // Generate the FSM context class. // class FooContext : // public statemap::FSMContext // { // public: // FOOContext(FOO& owner) // _source.print(_indent); _source.print("class "); _source.print(context); _source.println("Context :"); _source.print(_indent); _source.println(" public statemap::FSMContext"); _source.print(_indent); _source.println("{"); _source.print(_indent); _source.println("public:"); _source.println(); _source.print(_indent); _source.print(" "); _source.print(context); _source.print("Context("); _source.print(context); _source.println("& owner)"); _source.print(_indent); _source.println(" : _owner(owner)"); _source.print(_indent); _source.println(" {"); _source.print(_indent); _source.print(" setState("); _source.print(fsm.getStartState()); _source.println(");"); _source.print(_indent); _source.print(" "); _source.print(fsm.getStartState()); _source.println(".Entry(*this);"); _source.print(_indent); _source.println(" };"); _source.println(); _source.print(_indent); _source.print(" "); _source.print(context); _source.println("& getOwner() const"); _source.print(_indent); _source.println(" {"); _source.print(_indent); _source.println(" return (_owner);"); _source.print(_indent); _source.println(" };"); _source.println(); _source.print(_indent); _source.print(" "); _source.print(context); _source.println("State& getState() const"); _source.print(_indent); _source.println(" {"); _source.print(_indent); _source.println(" if (_state == NULL)"); _source.print(_indent); _source.println(" {"); // v. 1.3.1: If -noex was specified, then don't throw // exceptions. if (Smc.isNoExceptions() == false) { _source.print(_indent); _source.print(" throw "); _source.println( "statemap::StateUndefinedException();"); } else { _source.print(_indent); _source.println(" assert(1 == 0);"); } _source.print(_indent); _source.println(" }"); _source.println(); _source.print(_indent); _source.print(" return ("); _source.print(Smc.castType()); _source.print("<"); _source.print(context); _source.println("State&>(*_state));"); _source.print(_indent); _source.println(" };"); // 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(_indent); _source.print(" void "); _source.print(trans.getName()); _source.print("("); params = trans.getParameters(); for (pit = params.iterator(), separator = ""; pit.hasNext() == true; separator = ", ") { _source.print(separator); (pit.next()).accept(this); } _source.println(")"); _source.print(_indent); _source.println(" {"); // If -g was specified, then set the transition // name so it can be printed out. if (Smc.isDebug() == true) { _source.print(_indent); _source.print(" setTransition(\""); _source.print(trans.getName()); _source.println("\");"); } _source.print(_indent); _source.print(" (getState())."); _source.print(trans.getName()); _source.print("(*this"); for (SmcParameter param: params) { _source.print(", "); _source.print(param.getName());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -