📄 smcparser.sm
字号:
Default PushError { error("push transition missing closing paren.", ctxt.getLineNumber()); }}JumpStart{ LEFT_PAREN(token : SmcLexer.Token) JumpMap {} Default JumpError { error("\"jump\" must be followed by a '/'.", ctxt.getLineNumber()); }}JumpError{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default nil {}}JumpMap{ WORD(token : SmcLexer.Token) JumpEnd { setEndState(token.getValue()); } Default JumpError { error("Expecting a state name.", ctxt.getLineNumber()); }}JumpEnd{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} Default JumpError { error("jump transition missing closing paren.", ctxt.getLineNumber()); }}PopStart{ LEFT_PAREN(token : SmcLexer.Token) PopAction {} // A brace denotes the start of the actions. // It is acceptable not to provide a pop transition. LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default PopError { error("Expecting '(trans)' or '{' after pop.", ctxt.getLineNumber()); }}PopError{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default nil {}}PopAction{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} WORD(token : SmcLexer.Token) PopArgs { setEndState(token.getValue()); } Default PopError { error("Expecting either a pop transition or closing paren.", ctxt.getLineNumber()); }}PopArgs{ // No more pop arguments. Start collecting the actions. RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} // A comma signifies there are more arguments in this // transition. COMMA(token : SmcLexer.Token) PopArgsEnd {} Default PopError { error("Pop transition missing closing paren.", ctxt.getLineNumber()); }}PopArgsEnd Entry { setRawMode("(", ")"); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) ActionStart { setPopArgs(token.getValue()); }}ActionStart{ // A brace denotes the start of the actions. LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default ActionStartError { error("A '{' must proceed any action definitions.", ctxt.getLineNumber()); }}ActionEnd{ actionsDone(actions: List<SmcAction>, lineNumber: int) Transitions { setActions(actions); addGuard(); addTransition(); } actionsError Transitions {}}ActionStartError{ LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default nil {}}%%// This map parses transition parameters.%map ParamMap%%Start Entry { createParamList(); }{ // This is the parameter name. WORD(token: SmcLexer.Token) ParamSeparator { createParameter(token.getValue(), token.getLineNumber()); } // Empty parameter lists are fine. RIGHT_PAREN(token: SmcLexer.Token) pop(paramsDone, ctxt.getParamList(), token.getLineNumber()) {} // Perl/PHP parameter DOLLAR(token: SmcLexer.Token) [ctxt.getTargetLanguage() == Smc.PERL || ctxt.getTargetLanguage() == Smc.PHP || ctxt.getTargetLanguage() == Smc.GRAPH || ctxt.getTargetLanguage() == Smc.TABLE] Dollar {} // Anything else is an error. Go to the error state and // read in all remaining characters until the end paren // is found. Default Error { error("Invalid parameter syntax.", ctxt.getLineNumber()); }}Dollar{ // This is the parameter name. WORD(token: SmcLexer.Token) ParamSeparator { createParameter("$" + token.getValue(), token.getLineNumber()); } // Anything else is an error. Go to the error state and // read in all remaining characters until the end paren // is found. Default Error { error("Invalid parameter syntax.", ctxt.getLineNumber()); }}ParamSeparator{ // The parameter name and type are separated by a colon. COLON(token: SmcLexer.Token) ParamType {} // The parameter does *not* need a type if the target // language is typeless. COMMA(token: SmcLexer.Token) [ctxt.getTargetLanguage() == Smc.TCL || ctxt.getTargetLanguage() == Smc.GROOVY || ctxt.getTargetLanguage() == Smc.LUA || ctxt.getTargetLanguage() == Smc.PERL || ctxt.getTargetLanguage() == Smc.PHP || ctxt.getTargetLanguage() == Smc.PYTHON || ctxt.getTargetLanguage() == Smc.RUBY || ctxt.getTargetLanguage() == Smc.GRAPH || ctxt.getTargetLanguage() == Smc.TABLE] Start { addParameter(); } RIGHT_PAREN(token: SmcLexer.Token) [ctxt.getTargetLanguage() == Smc.TCL || ctxt.getTargetLanguage() == Smc.GROOVY || ctxt.getTargetLanguage() == Smc.LUA || ctxt.getTargetLanguage() == Smc.PERL || ctxt.getTargetLanguage() == Smc.PHP || ctxt.getTargetLanguage() == Smc.PYTHON || ctxt.getTargetLanguage() == Smc.RUBY || ctxt.getTargetLanguage() == Smc.GRAPH || ctxt.getTargetLanguage() == Smc.TABLE] pop(paramsDone, ctxt.getParamList(), token.getLineNumber()) { addParameter(); } // The target language is typed. This is not allowed. COMMA(token: SmcLexer.Token) Error { error("Parameter type missing.", token.getLineNumber()); } RIGHT_PAREN(token: SmcLexer.Token) pop(paramsError, ctxt.getParamList(), token.getLineNumber()) { error("Parameter type missing.", token.getLineNumber()); } Default Error { error("Invalid parameter syntax.", ctxt.getLineNumber()); }}ParamType Entry { setRawMode("(", ")", ","); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) NextParam { setParamType(token.getValue()); }}NextParam{ COMMA(token: SmcLexer.Token) Start { addParameter(); } RIGHT_PAREN(token: SmcLexer.Token) pop(paramsDone, ctxt.getParamList(), token.getLineNumber()) { addParameter(); } Default Error { error("Invalid parameter syntax.", ctxt.getLineNumber()); }}Error Entry { setRawMode("(", ")"); clearParameter(); } Exit { setCookedMode(); }{ // Delete any collected parameters. SOURCE(token: SmcLexer.Token) pop(paramsError, ctxt.getParamList(), token.getLineNumber()) {}}%%// This map parses transition actions.// Transition actions are of the form:// WORD '(' SOURCE ')' ';'//// VB and C#: Transition actions may also have the form:// WORD '=' SOURCE ';'//%map ActionMap%%Start{ // This word is the action name. WORD(token: SmcLexer.Token) ActionName { createAction(token.getValue(), token.getLineNumber()); } RIGHT_BRACE(token: SmcLexer.Token) pop(actionsDone, ctxt.getActionList(), token.getLineNumber()) {} Default ActionError { clearActions(); error("Expecting either a method name or a '}'", ctxt.getLineNumber()); }}ActionName{ LEFT_PAREN(token: SmcLexer.Token) ActionArgs/push(ArgsMap::Start) { createArgList(); } // .Net uses some syntactic sugar instead of getter/setter // methods. Let say a class has a member data _name. In Java // and C++ you do "name = obj.getName();" to retrieve _name // and "obj.setName(name);" to set _name. // In .Net you do "name = obj.Name" and "obj.Name = name" // where Name is a property with Get and Set routines. // So you are still doing method calls but .Net uses the // "=" operator to hide the fact. // // I don't like that. // // Either way, it is part of .Net languages and SMC must // allow .Net users to access this capability. EQUAL(token: SmcLexer.Token) [ctxt.getTargetLanguage() != Smc.VB && ctxt.getTargetLanguage() != Smc.C_SHARP] ActionError { clearActions(); error("'=' property assignment may only be used with -vb or -csharp.", token.getLineNumber()); } EQUAL(token: SmcLexer.Token) PropertyAssignment { setProperty(true); createArgList(); } Default ActionError { clearActions(); error( "Expecting an open paren after the method name", ctxt.getLineNumber()); }}ActionArgs{ argsDone(args: List<String>) ActionEnd { setActionArgs(args); } argsError ActionError {}}ActionEnd{ // Look for the semicolon. SEMICOLON(token: SmcLexer.Token) Start { addAction(); } Default ActionError { error("Expecting a ';' after closing paren", ctxt.getLineNumber()); }}PropertyAssignment Entry { setRawMode(";"); } Exit { setCookedMode(); }{ // .Net property assignment takes only one argument. SOURCE(token: SmcLexer.Token) Start { createArgument(token.getValue(), token.getLineNumber()); addArgument(); setActionArgs(ctxt.getArgsList()); addAction(); } Default ActionError { error("Missing ';' at end of property assignment", ctxt.getLineNumber()); }}// Wait here for a right brace which we will assume to be the// action body's end.ActionError{ RIGHT_BRACE(token: SmcLexer.Token) pop(actionsError) {} Default nil {}}%%// This map parses an action's arguments.%map ArgsMap%%Start Entry { setRawMode("(", ")", ","); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) NextArg { createArgument(token.getValue(), token.getLineNumber()); }}NextArg{ COMMA(token: SmcLexer.Token) Start { addArgument(); } RIGHT_PAREN(token: SmcLexer.Token) pop(argsDone, ctxt.getArgsList()) { addArgument(); } Default Error { error("Missing ',' or closing paren after argument.", ctxt.getLineNumber()); }}Error Entry { setRawMode("{", "}"); clearArguments(); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) pop(argsError) {}}%%
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -