📄 smcparser.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) 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.// Chris Liscio contributed the Objective-C code generation// and examples/ObjC.//// RCS ID// $Id: SmcParser.java,v 1.16 2007/11/19 18:53:21 fperrad Exp $//// CHANGE LOG// (See bottom of file.)//package net.sf.smc;import java.io.IOException;import java.io.InputStream;import java.io.PrintStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public final class SmcParser{//---------------------------------------------------------------// Member Methods// /** * Creates a parser for the named FSM in the given input * stream. If <code>debugFlag</code> is <code>true</code>, * then the parser and lexer debug output will be generated. * @param fsmName the finite state machine's name. * @param istream the input stream contains the SMC code. * @param debugFlag if true, turn on debug output. */ public SmcParser(String name, InputStream istream, boolean debugFlag) { _name = name; _messages = new ArrayList<SmcMessage>(); _lexer = new SmcLexer(istream, debugFlag); _parserFSM = new SmcParserContext(this); _parserFSM.setDebugFlag(debugFlag); } /** * Parses the named FSM in the given input stream and returns * the finite state machine. */ public SmcFSM parse() throws IOException, IllegalAccessException, InvocationTargetException { SmcLexer.Token token = null; int tokenType; Object[] params = new Object[1]; _mapInProgress = null; _stateInProgress = null; _transitionName = null; _transitionInProgress = null; _guardInProgress = null; _paramInProgress = null; _actionInProgress = null; _argInProgress = null; _paramList = null; _actionList = null; _argList = null; _parseStatus = true; _quitFlag = false; _fsm = new SmcFSM(_name); // Start lexing in cooked mode. _lexer.setCookedMode(); // Read all the tokens into a list. tokenType = SmcLexer.TOKEN_NOT_SET; while (_quitFlag == false && (token = _lexer.nextToken()) != null) { tokenType = token.getType(); _lineNumber = token.getLineNumber(); // Is the token type valid? if (tokenType <= SmcLexer.TOKEN_NOT_SET && tokenType >= SmcLexer.TOKEN_COUNT) { // No. error("Undefined token type (" + Integer.toString(tokenType) + ")", token.getLineNumber()); _quitFlag = true; _parseStatus = false; } // If the last token is a failure, don't go on. else if (tokenType == SmcLexer.DONE_FAILED) { _quitFlag = true; _parseStatus = false; error(token.getValue(), token.getLineNumber()); } // If the last token is success, don't go on either. else if (tokenType == SmcLexer.DONE_SUCCESS) { _quitFlag = true; } else { // Issue a transition for this token. params[0] = token; _TransMethod[tokenType].invoke(_parserFSM, params); } } // If the parse failed, delete the tree. if (_parseStatus == false) { _fsm = null; } return (_fsm); } /** * Returns the parser's warning and error messages list. * @return the parser's warning and error messages list. */ public List<SmcMessage> getMessages() { return (_messages); } //----------------------------------------------------------- // State Machine Guards // /* package */ boolean isValidHeader() { String context = _fsm.getContext(); String start = _fsm.getStartState(); return (context != null && context.length() > 0 && start != null && start.length() > 0); } /* package */ boolean isValidStartState(String name) { int index; boolean retval = false; // The name must be of the form "<id>::<id>". index = name.indexOf("::"); // Fail if "::" does not appear at all or appears // more than once. if (index >= 0 && name.indexOf("::", (index + 1)) < 0) { // Given how the lexer works, we are guaranteed // that the two identifiers are valid. retval = true; } return (retval); } /* package */ boolean isDuplicateMap(String name) { return (_fsm.findMap(name) == null ? false : true); } /* package */ boolean isDuplicateState(String name) { return (_mapInProgress.isKnownState(name)); } // // end of State Machine Guards //----------------------------------------------------------- //----------------------------------------------------------- // State Machine Actions // /* package */ void warning(String errorMsg, int lineNumber) { _messages.add( new SmcMessage(_name, lineNumber, SmcMessage.WARNING, errorMsg)); return; } /* package */ void error(String errorMsg, int lineNumber) { _messages.add( new SmcMessage(_name, lineNumber, SmcMessage.ERROR, errorMsg)); _parseStatus = false; return; } /* package */ int getLineNumber() { return (_lineNumber); } /* package */ int getTargetLanguage() { return (Smc._targetLanguage.index()); } // Put the lexer into raw mode. /* package */ void setRawMode(String openChar, String closeChar) { _lexer.setRawMode(openChar.charAt(0), closeChar.charAt(0)); return; } // Put the lexer into the raw mode used for // collecting parameter types. /* package */ void setRawMode(String openChar, String closeChar, String separator) { _lexer.setRawMode(openChar.charAt(0), closeChar.charAt(0), separator.charAt(0)); return; } // Put the lexer into the raw mode used for collecting // parameter types. /* package */ void setRawMode(String closeChars) { _lexer.setRawMode(closeChars); return; } // Put the lexer into cooked mode. /* package */ void setCookedMode() { _lexer.setCookedMode(); return; } /* package */ void setHeaderLine(int lineNumber) { _fsm.setHeaderLine(lineNumber); return; } /* package */ void setSource(String source) { String src = _fsm.getSource(); if (src != null && src.length() > 0) { warning("%{ %} source previously specified, new " + "source ignored.", _lineNumber); } else { _fsm.setSource(source); } return; } /* package */ void setStartState(String stateName) { String start = _fsm.getStartState(); if (start != null && start.length() > 0) { warning("%start previously specified, new start " + "state ignored.", _lineNumber); } else { _fsm.setStartState(stateName); } return; } /* package */ void setContext(String name) { String context = _fsm.getContext(); if (context != null && context.length() > 0) { warning("%class previously specified, new context " + "ignored.", _lineNumber); } else { _fsm.setContext(name); } return; } /* package */ void setPackageName(String name) { String pkg = _fsm.getPackage(); if (pkg != null && pkg.length() > 0) { warning("%package previously specified, " + "new package ignored.", _lineNumber); } else { _fsm.setPackage(name.trim()); } return; } /* package */ void addImport(String name) { _fsm.addImport(name.trim()); return; } /* package */ void addDeclare(String name) { _fsm.addDeclare(name.trim()); return; } /* package */ void setHeader(String name) { String header = _fsm.getHeader(); if (header != null && header.length() > 0) { warning("%header previously specified, " + "new header file ignored.", _lineNumber); } else { _fsm.setHeader(name.trim()); } return; } /* package */ void addInclude(String name) { _fsm.addInclude(name.trim()); return; } /* package */ void setAccessLevel(String level) { String accessLevel = _fsm.getAccessLevel(); if (accessLevel != null && accessLevel.length() > 0) { warning("%access previously specified, " + "new access level ignored.", _lineNumber); } else { _fsm.setAccessLevel(level.trim()); } return; } /* package */ void addMap() { if (_mapInProgress == null) { error("There is no in-progress map to add", _lineNumber); } else { // If this map does not have a default state, then // create one now. if (_mapInProgress.hasDefaultState() == false) { SmcState DefaultState = new SmcState( "Default", _mapInProgress.getLineNumber(), _mapInProgress); _mapInProgress.addState(DefaultState); } _fsm.addMap(_mapInProgress); _mapInProgress = null; } return; } /* package */ void createMap(String name, int lineNumber) { if (_mapInProgress != null) { error("Cannot create new map while still filling " + "in previous map (" + _mapInProgress.getName() + ").", lineNumber); } else { if (_parserFSM.getDebugFlag() == true) { PrintStream os = _parserFSM.getDebugStream(); os.println("CREATE MAP : " + name + "(" + Integer.toString(lineNumber) + ")"); } _mapInProgress = new SmcMap(name, lineNumber, _fsm); } return; } /* package */ void addState() { if (_mapInProgress == null) { error("There is no in-progress map to which the " + "state may be added.", _lineNumber); } else if (_stateInProgress == null) { error("There is no in-progrss state to add to the " + "map.", _lineNumber); } else { _mapInProgress.addState(_stateInProgress); _stateInProgress = null; } return; } /* package */ void createState(String name, int lineNumber) { SmcState retval; if (_stateInProgress != null) { error("Cannot create new state while still " + "filling in previous state (" + _stateInProgress.getName() + ").", lineNumber); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -