📄 smcparser.sm
字号:
// -*- tab-width: 4; -*-%{/* * 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) 2000 - 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, Perl code generation and examples/Perl, * Ruby code generation and examples/Ruby, Lua code generation * and examples/Lua, Groovy code generation and examples/Groovy. * Chris Liscio contributed the Objective-C code generation * and examples/ObjC. * * smcParser -- * * This state machine defines the state machine language. * * RCS ID * $Id: SmcParser.sm,v 1.20 2008/04/22 16:05:24 fperrad Exp $ * * CHANGE LOG * $Log: SmcParser.sm,v $ * Revision 1.20 2008/04/22 16:05:24 fperrad * - add PHP language (patch from Toni Arnold) * * Revision 1.19 2008/01/22 08:56:55 fperrad * - fix : allows Perl parameter with graph generation * * Revision 1.18 2007/11/19 18:53:21 fperrad * + add : jump syntax * jump uses the same syntax as push, * allows transition between states of different maps but without stacking a return context. * * Revision 1.17 2007/07/16 06:28:06 fperrad * + Added Groovy generator. * * Revision 1.16 2007/02/21 13:56:16 cwrapp * Moved Java code to release 1.5.0 * * Revision 1.15 2007/01/15 00:23:51 cwrapp * Release 4.4.0 initial commit. * * Revision 1.14 2007/01/03 15:23:05 fperrad * + Added Lua generator. * * Revision 1.13 2006/09/16 15:04:29 cwrapp * Initial v. 4.3.3 check-in. * * Revision 1.12 2006/07/11 18:17:01 cwrapp * Removed errors regarding percent keywords. * * Revision 1.11 2006/04/22 12:45:26 cwrapp * Version 4.3.1 * * Revision 1.10 2005/09/14 01:51:33 cwrapp * Changes in release 4.2.0: * New features: * * None. * * Fixed the following bugs: * * + (Java) -java broken due to an untested minor change. * * Revision 1.9 2005/08/26 15:21:34 cwrapp * Final commit for release 4.2.0. See README.txt for more information. * * Revision 1.8 2005/07/07 12:11:56 fperrad * Add a new token '$' for Perl language. * The type of parameter is optional for Python, Per & Ruby. * * Revision 1.7 2005/06/30 10:44:23 cwrapp * Added %access keyword which allows developers to set the generate Context * class' accessibility level in Java and C#. * * Revision 1.6 2005/05/28 19:28:42 cwrapp * Moved to visitor pattern. * * Revision 1.5 2005/02/21 15:37:52 charlesr * Added Francois Perrad to Contributors section for Python work. * * Revision 1.4 2005/02/21 15:21:21 charlesr * Added -graph target as allowing %include, %declare and %import. * * Revision 1.3 2005/02/03 17:06:21 charlesr * SmcParser.warning() and .error() methods now take a line * number argument. All calls to these method within the * parser's FSM have been modified. * * Revision 1.2 2004/09/06 16:41:32 charlesr * Added "property = value" syntax. Added C# support. * * Revision 1.1 2004/05/31 13:56:34 charlesr * Added support for VB.net code generation. * * Revision 1.0 2003/12/14 21:06:00 charlesr * Initial revision * */%}%class SmcParser%start ParserMap::Start%package net.sf.smc%import java.util.List%map ParserMap%%Start{ // The statemap can start with an optional raw source code // section or go straight to the map definitions. SOURCE(token : SmcLexer.Token) nil { setSource(token.getValue()); setHeaderLine(token.getLineNumber()); } // The state map's start state and class name must be // specified before the map name. // The header file is optional since its name can be // deduced from the class name (maybe). The class name // and header file are ignored when generating Tcl code. START_STATE(token : SmcLexer.Token) StartState { setHeaderLine(token.getLineNumber()); } CLASS_NAME(token : SmcLexer.Token) Context { setHeaderLine(token.getLineNumber()); } HEADER_FILE(token : SmcLexer.Token) HeaderFile { setHeaderLine(token.getLineNumber()); } INCLUDE_FILE(token: SmcLexer.Token) IncludeFile { setHeaderLine(token.getLineNumber()); } PACKAGE_NAME(token : SmcLexer.Token) Package {} IMPORT(token : SmcLexer.Token) Import { setHeaderLine(token.getLineNumber()); } DECLARE(token : SmcLexer.Token) Declare { setHeaderLine(token.getLineNumber()); } // The %access keyword is allowed for all target languages // but ignored if target language does not support setting // the class accessibility level. ACCESS(token: SmcLexer.Token) Access { setHeaderLine(token.getLineNumber()); } MAP_NAME(token: SmcLexer.Token) [ctxt.isValidHeader() == true] MapName { setHeaderLine(token.getLineNumber()); } MAP_NAME(token: SmcLexer.Token) StartError { error("%map not preceded by %start and %class.", token.getLineNumber()); setHeaderLine(token.getLineNumber()); } Default StartError { error( "Expecting \"%{ source %}\", %start, or %class.", ctxt.getLineNumber()); setHeaderLine(ctxt.getLineNumber()); }}Context{ WORD(token: SmcLexer.Token) Start { setContext(token.getValue()); } Default StartError { error("Missing name after %class.", ctxt.getLineNumber()); }}// The state name must be of the form "map::state".StartState{ WORD(token : SmcLexer.Token) [ctxt.isValidStartState(token.getValue()) == true] Start { setStartState(token.getValue()); } WORD(token : SmcLexer.Token) StartError { error( "Start state must be of the form \"map::state\".", token.getLineNumber()); } Default StartError { error("Missing state after %start.", ctxt.getLineNumber()); }}HeaderFile Entry { setRawMode("\n\r\f"); } Exit { setCookedMode(); }{ SOURCE(token : SmcLexer.Token) Start { setHeader(token.getValue()); } Default StartError { error("Missing header file after %header.", ctxt.getLineNumber()); }}IncludeFile Entry { setRawMode("\n\r\f"); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) Start { addInclude(token.getValue()); } Default StartError { error("Missing include file after %include.", ctxt.getLineNumber()); }}Package{ WORD(token: SmcLexer.Token) Start { setPackageName(token.getValue()); } Default StartError { error("Missing name after %package.", ctxt.getLineNumber()); }}Import Entry { setRawMode("\n\r\f"); } Exit { setCookedMode(); }{ SOURCE(token : SmcLexer.Token) Start { addImport(token.getValue()); } Default StartError { error("Missing name after %import.", ctxt.getLineNumber()); }}Declare Entry { setRawMode("\n\r"); } Exit { setCookedMode(); }{ SOURCE(token : SmcLexer.Token) Start { addDeclare(token.getValue()); } Default StartError { error("Missing name after %declare.", ctxt.getLineNumber()); }}Access Entry { setRawMode("\n\r\f"); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) Start { setAccessLevel(token.getValue()); } Default StartError { error("Missing access level after %access.", ctxt.getLineNumber()); }}// Remain in this state until a known good token is found.StartError{ START_STATE(token : SmcLexer.Token) StartState { setHeaderLine(token.getLineNumber()); } CLASS_NAME(token : SmcLexer.Token) Context { setHeaderLine(token.getLineNumber()); } HEADER_FILE(token : SmcLexer.Token) HeaderFile { setHeaderLine(token.getLineNumber()); } PACKAGE_NAME(token : SmcLexer.Token) Package {} IMPORT(token : SmcLexer.Token) Import { setHeaderLine(token.getLineNumber()); } DECLARE(token : SmcLexer.Token) Declare { setHeaderLine(token.getLineNumber()); } ACCESS(token: SmcLexer.Token) Access {} MAP_NAME(token : SmcLexer.Token) [ctxt.isValidHeader() == true] MapName { setHeaderLine(token.getLineNumber()); } MAP_NAME(token : SmcLexer.Token) StartError { error("%map not preceded by %start and %class.", token.getLineNumber()); } Default nil {}}MapStart{ MAP_NAME(token : SmcLexer.Token) MapName {} Default MapStartError { error("Expecting %map.", ctxt.getLineNumber()); }}MapStartError{ MAP_NAME(token : SmcLexer.Token) MapName {} Default nil {}}MapName{ WORD(token : SmcLexer.Token) [ctxt.isDuplicateMap(token.getValue()) == true] MapStates { error("Duplicate map name.", token.getLineNumber()); createMap(token.getValue(), token.getLineNumber()); } // The next word transition is the map's name. WORD(token : SmcLexer.Token) MapStates { createMap(token.getValue(), token.getLineNumber()); } EOD(token : SmcLexer.Token) States { error("Name expected after \"%map\".", token.getLineNumber()); createMap(token.getValue(), token.getLineNumber()); } Default nil { error("Name expected after \"%map\".", ctxt.getLineNumber()); }}MapStates{ // %% marks the start of the map states. EOD(token : SmcLexer.Token) States {} WORD(token : SmcLexer.Token) StateStart { error("Expecting %% after \"%map mapname\".", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); } Default MapStatesError { error("Expecting %% after \"%map mapname\".", ctxt.getLineNumber()); }}MapStatesError{ EOD(token : SmcLexer.Token) States {} MAP_NAME(token : SmcLexer.Token) MapName { addMap(); } WORD(token : SmcLexer.Token) StateStart { createState(token.getValue(), token.getLineNumber()); } Default nil {}}States{ // The "%%" means we have reached the end of this map's // definition. EOD(token : SmcLexer.Token) MapStart { addMap(); } // A word is the next state's name. WORD(token : SmcLexer.Token) [ctxt.isDuplicateState(token.getValue()) == true] StateStart { error("Duplicate state name.", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); } WORD(token : SmcLexer.Token) StateStart { createState(token.getValue(), token.getLineNumber()); } // Error transitions. ENTRY(token : SmcLexer.Token) EntryStart { error( "Expecting either a new state definition or end of map (%%).", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); } EXIT(token : SmcLexer.Token) ExitStart { error( "Expecting either a new state definition or end of map (%%).", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); } LEFT_BRACE(token : SmcLexer.Token) Transitions { error( "Expecting either a new state definition or end of map (%%).", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); } EQUAL(token: SmcLexer.Token) Transitions { error( "Expecting either a new state definition or end of map (%%).", token.getLineNumber()); createState(token.getValue(), token.getLineNumber()); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -