📄 smcphpgenerator.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 - 2007. Charles W. Rapp.// All Rights Reserved.//// Port to Python by Francois Perrad, francois.perrad@gadz.org// Copyright 2004, Francois Perrad.// 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.// Toni Arnold contributed the PHP code generation and// examples/Php.//// PHP note:// "Exit" and "Default" are PHP keywords, so for code generation,// "Exit_" and "Default_" is used instead - but the .sm input file// still should use "Default" for default transitions.//// RCS ID// $Id: SmcPhpGenerator.java,v 1.1 2008/04/22 16:05:24 fperrad Exp $//// CHANGE LOG// (See the bottom of this file.)//package net.sf.smc;import java.io.PrintStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * Visits the abstract syntax tree, emitting Python code. * @see SmcElement * @see SmcCodeGenerator * @see SmcVisitor * * @author Francois Perrad */public final class SmcPhpGenerator extends SmcCodeGenerator{//---------------------------------------------------------------// Member methods// public SmcPhpGenerator(String srcfileBase) { super (srcfileBase, "{0}{1}_sm.{2}", "php"); } // end of SmcPhpGenerator(String) // State names like "map::state" must be changed to // "map::$state" for accessing static members in PHP. private String phpStateName(String state) { int index; if ((index = state.indexOf("::")) >= 0) { return state.substring(0, index) + "::$" + state.substring(index + 2); } else { return state; } } public void visit(SmcFSM fsm) { String context = fsm.getContext(); String rawSource = fsm.getSource(); String startState = fsm.getStartState(); String phpState; List<SmcMap> maps = fsm.getMaps(); List<SmcTransition> transitions; List<SmcParameter> params; Iterator<SmcParameter> pit; String transName; String separator; _source.println("<?php"); _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(); // Dump out the raw source code, if any. if (rawSource != null && rawSource.length () > 0) { _source.println(rawSource); _source.println(); } _source.println("require_once 'StateMachine/statemap.php';"); _source.println(); // Do user-specified imports now. for (String imp: fsm.getImports()) { _source.print("require_once '"); _source.print(imp); _source.println("';"); } // Declare the state class. _source.println(); _source.print("class "); _source.print(context); _source.println("State extends State {"); _source.println(); _source.println(" public function Entry($fsm) {"); _source.println(" }"); _source.println(); _source.println(" public function Exit_($fsm) {"); _source.println(" }"); _source.println(); // Get the transition list. // Generate the default transition definitions. transitions = fsm.getTransitions(); for (SmcTransition trans: transitions) { params = trans.getParameters(); // Don't generate the Default transition here. if (trans.getName().equals("Default") == false) { _source.print(" public function "); _source.print(trans.getName()); _source.print("($fsm"); for (SmcParameter param: params) { _source.print(", "); param.accept(this); } _source.println(") {"); // If this method is reached, that means that // this transition was passed to a state which // does not define the transition. Call the // state's default transition method. _source.println(" $this->Default_($fsm);"); _source.println(" }"); _source.println(); } } // Generate the overall Default transition for all maps. _source.println(" public function Default_($fsm) {"); if (Smc.isDebug() == true) { _source.println( " if ($fsm->getDebugFlag() == true) {"); _source.println( " fwrite($fsm->getDebugStream(), \"TRANSITION : Default\\n\");"); _source.println( " }"); } _source.println( " $state = $fsm->getState()->getName();"); _source.println( " $transition = $fsm->getTransition();"); _source.println( " $msg = \"\\n\\tState: $state\\n\\tTransition: $transition\";"); _source.println( " throw new TransitionUndefinedException($msg);"); _source.println(" }"); _source.println("}"); // end of state class // Have each map print out its source code now. for (SmcMap map: maps) { map.accept(this); } // The context class contains all the state classes as // inner classes, so generate the context first rather // than last. _source.println(); _source.print("class "); _source.print(context); _source.println("_sm extends FSMContext {"); _source.println(); // Generate the context class' constructor. _source.println(" public function __construct($owner) {"); _source.println( " parent::__construct();"); _source.println(" $this->_owner = $owner;"); phpState = phpStateName(startState); _source.print(" $this->setState("); _source.print(phpState); _source.println(");"); // Execute the start state's entry actions. _source.print(" "); _source.print(phpState); _source.println("->Entry($this);"); _source.println(" }"); _source.println(); // Generate the transition methods. for (SmcTransition trans: transitions) { transName = trans.getName(); params = trans.getParameters(); if (transName.equals("Default") == false) { _source.print(" public function "); _source.print(transName); _source.print("("); // Now output the transition's parameters. params = trans.getParameters(); for (pit = params.iterator(), separator = ""; pit.hasNext() == true; separator = ", ") { _source.print(separator); (pit.next()).accept(this); } _source.println(") {"); // Save away the transition name in case it is // need in an UndefinedTransitionException. _source.print(" $this->_transition = \""); _source.print(transName); _source.println("\";"); _source.print(" $this->getState()->"); _source.print(transName); _source.print("($this"); for (pit = params.iterator(); pit.hasNext() == true; ) { _source.print(", "); _source.print((pit.next()).getName()); } _source.println(");"); _source.println( " $this->_transition = NULL;"); _source.println(" }"); _source.println(); } } // getState() method. _source.println(" public function getState() {"); _source.println(" if ($this->_state == NULL) {"); _source.println( " throw new StateUndefinedException();"); _source.println(" }"); _source.println(" return $this->_state;"); _source.println(" }"); _source.println(); // getOwner() method. _source.println(" public function getOwner() {"); _source.println(" return $this->_owner;"); _source.println(" }"); _source.println(); _source.println("}"); // end of context class _source.println(); _source.println("?>"); return; } // end of visit(SmcFSM) public void visit(SmcMap map) { List<SmcTransition> definedDefaultTransitions; SmcState defaultState = map.getDefaultState(); String context = map.getFSM().getContext(); String mapName = map.getName(); List<SmcState> states = map.getStates(); boolean needPass = true; // Initialize the default transition list to all the // default state's transitions. if (defaultState != null) { definedDefaultTransitions = defaultState.getTransitions(); } else { definedDefaultTransitions = new ArrayList<SmcTransition>(); } // Declare the map default state class. _source.println(); _source.print("class "); _source.print(mapName); _source.print("_Default extends "); _source.print(context); _source.println("State {"); // Declare the user-defined default transitions first. for (SmcTransition transition: definedDefaultTransitions) { transition.accept(this); } // If -reflect was specified, then generate the // _transitions table. if (Smc.isReflection() == true) { List<SmcTransition> allTransitions = map.getFSM().getTransitions(); String transName; int transDefinition; // Generate the getTransitions() method. _source.println(); _source.println(" public function getTransitions() {"); _source.println(" return array("); // Now place all transition names and states into the // map. for (SmcTransition transition: allTransitions) { transName = transition.getName(); // If the transition is defined in this map's // default state, then the value is 2. if (definedDefaultTransitions.contains( transition) == true) { transDefinition = 2; } // Otherwise the value is 0 - undefined. else { transDefinition = 0; } _source.print(" '"); _source.print(transName); _source.print("' => "); _source.print(transDefinition); _source.println(","); } _source.println(" );"); _source.println(" }"); } _source.println(); _source.println("}"); // end of default state class // Have each state now generate its code. for (SmcState state: states) { state.accept(this); } // Declare and initialize the map class. // In PHP, static objects need to be instantiated // outside of the class, see // http://ch2.php.net/manual/en/language.oop5.static.php#51627 _source.println(); _source.print("class "); _source.print(mapName); _source.println(" {"); // declare the static members
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -