📄 smcparser.sm
字号:
MAP_NAME(token : SmcLexer.Token) MapName { error("Expecting \"%%\" before another \"%map\".", token.getLineNumber()); addMap(); } Default nil { error( "Expecting either a new state definition or end of map (%%).", ctxt.getLineNumber()); }}StateStart{ // This state has an entry actions. ENTRY(token : SmcLexer.Token) EntryStart {} // This state has an exit action. EXIT(token : SmcLexer.Token) ExitStart {} // The left brace marks the start of the transitions. LEFT_BRACE(token : SmcLexer.Token) Transitions {} Default StateStartError { error( "After the state name is given, then either an entry action, exit action or '{' is expected.", ctxt.getLineNumber()); }}StateStartError{ ENTRY(token : SmcLexer.Token) EntryStart {} EXIT(token : SmcLexer.Token) ExitStart {} LEFT_BRACE(token : SmcLexer.Token) Transitions {} Default nil {}}EntryStart{ LEFT_BRACE(token : SmcLexer.Token) EntryEnd/push(ActionMap::Start) { createActionList(); } Default StateStartError { error("A '{' is expected after Entry.", ctxt.getLineNumber()); }}EntryEnd{ actionsDone(actions: List<SmcAction>, lineNumber: int) StateStart { setEntryAction(actions); } actionsError StartState {}}ExitStart{ LEFT_BRACE(token : SmcLexer.Token) ExitEnd/push(ActionMap::Start) { createActionList(); } Default StateStartError { error("A '{' is expected after Exit.", ctxt.getLineNumber()); }}ExitEnd{ actionsDone(actions: List<SmcAction>, lineNumber: int) StateStart { setExitAction(actions); } actionsError StateStart {}}Transitions{ // A '}' is the end of the transitions. // Look for the next state. RIGHT_BRACE(token : SmcLexer.Token) States { addState(); } // This is the transition name. WORD(token : SmcLexer.Token) TransStart { storeTransitionName(token.getValue()); } Default TransError { error("Expecting either a new transition or a '}'.", ctxt.getLineNumber()); }}TransError{ RIGHT_BRACE(token : SmcLexer.Token) States { addState(); } WORD(token : SmcLexer.Token) TransStart { storeTransitionName(token.getValue()); } Default nil {}}TransStart{ // A '(' means this transition has parameters. LEFT_PAREN(token : SmcLexer.Token) TransParams/push(ParamMap::Start) {} // A '[' denotes a guard. Since the code between the brackets // may be raw source code, place the lexer in raw source code // mode. This means the lexer will not process the characters // by passing them through the lexer FSM. LEFT_BRACKET(token : SmcLexer.Token) TransGuard { createTransition(token.getLineNumber()); } // NOTE: Now that SMC allows guards to be complex condition // expressions, it is no longer possible to check for // duplicate guards. PUSH(token : SmcLexer.Token) PushStart { createTransition(token.getLineNumber()); createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_PUSH); setEndState("nil"); } POP(token : SmcLexer.Token) PopStart { createTransition(token.getLineNumber()); createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_POP); } JUMP(token : SmcLexer.Token) JumpStart { createTransition(token.getLineNumber()); createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); } // This word is the end state. Now get the actions. WORD(token : SmcLexer.Token) SimpleTrans { createTransition(token.getLineNumber()); createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState(token.getValue()); } Default TransStartError { error("Expecting either a guard, \"push\", \"pop\", \"jump\" or end state.", ctxt.getLineNumber()); // Need to create a dummy transition so that error // handling will function. createTransition(ctxt.getLineNumber()); }}TransStartError{ // A '(' means this transition has parameters. LEFT_PAREN(token : SmcLexer.Token) TransParams/push(ParamMap::Start) {} // A '[' means this transition is guarded. Have the lexer // collect the raw source code. LEFT_BRACKET(token : SmcLexer.Token) TransGuard {} // A '{' is the start of the transition actions. LEFT_BRACE(token: SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState("End state missing"); createActionList(); } PUSH(token : SmcLexer.Token) PushStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_PUSH); setEndState("nil"); } POP(token : SmcLexer.Token) PopStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_POP); } JUMP(token : SmcLexer.Token) JumpStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState("nil"); } // One way or another this transition is now kaput. RIGHT_BRACE(token: SmcLexer.Token) Transitions { addGuard(); addTransition(); } Default nil {}}// Wait here for the transition parameter list to be returned.TransParams{ // The "Default" transition may not have parameters. // But create a bogus transition before continuing. paramsDone(params: List<SmcParameter>, lineNumber: int) [ctxt.getTransitionName().equalsIgnoreCase( "Default") == true && params.isEmpty() == false] TransNext { error("Default transitions may not have parameters.", lineNumber); createTransition(params, lineNumber); } paramsDone(params: List<SmcParameter>, lineNumber: int) TransNext { createTransition(params, lineNumber); } // Create a bogus transition and keep going. paramsError(params: List<SmcParameter>, lineNumber: int) TransNext { createTransition(params, lineNumber); }}TransNext{ // A bracket denotes a guard. LEFT_BRACKET(token : SmcLexer.Token) TransGuard {} // NOTE: Now that SMC allows guards to be complex condition // expressions, it is no longer possible to check for // duplicate guards. PUSH(token : SmcLexer.Token) PushStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_PUSH); setEndState("nil"); } POP(token : SmcLexer.Token) PopStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_POP); } JUMP(token : SmcLexer.Token) JumpStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState("nil"); } // This word is the end state. Now get the actions. WORD(token : SmcLexer.Token) SimpleTrans { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState(token.getValue()); } Default TransNextError { error("Expecting either a guard, \"push\", \"pop\", \"jump\" or end state.", ctxt.getLineNumber()); }}TransNextError{ // Transition parameters have already been defined. LEFT_PAREN(token : SmcLexer.Token) nil {} // A bracket means this transition is guarded. LEFT_BRACKET(token : SmcLexer.Token) TransGuard {} PUSH(token : SmcLexer.Token) PushStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_PUSH); setEndState("nil"); } POP(token : SmcLexer.Token) PopStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_POP); } JUMP(token : SmcLexer.Token) JumpStart { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState("nil"); } WORD(token : SmcLexer.Token) SimpleTrans { createGuard(ctxt.getTransitionName(), "", token.getLineNumber()); setTransType(Smc.TRANS_SET); setEndState(token.getValue()); } Default nil {}}// Because the lexer is operating in raw mode, the lexer will// return either a SOURCE token or an ERROR token. Since ERROR// tokens are not passed into this FSM, then only the SOURCE// token must be handled.TransGuard Entry { setRawMode("[", "]"); } Exit { setCookedMode(); }{ SOURCE(token: SmcLexer.Token) EndState { createGuard(ctxt.getTransitionName(), token.getValue(), token.getLineNumber()); }}EndState{ // NOTE: Now that SMC allows guards to be complex condition // expressions, it is no longer possible to check for // duplicate guards. PUSH(token : SmcLexer.Token) PushStart { setTransType(Smc.TRANS_PUSH); setEndState("nil"); } POP(token : SmcLexer.Token) PopStart { setTransType(Smc.TRANS_POP); } JUMP(token : SmcLexer.Token) JumpStart { setTransType(Smc.TRANS_SET); setEndState("nil"); } WORD(token : SmcLexer.Token) SimpleTrans { setTransType(Smc.TRANS_SET); setEndState(token.getValue()); } Default EndStateError { error("Expecting either \"push\", \"pop\", \"jump\" or end state.", ctxt.getLineNumber()); }}EndStateError{ LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default nil {}}SimpleTrans{ // A slash means that this is really a push transition. SLASH(token: SmcLexer.Token) PushTransition { setTransType(Smc.TRANS_PUSH); } // 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()); }}// This is the push part of a "<state1>/push(<state2>)" end statefd// <state1> has been parse, now look for the push.PushTransition{ PUSH(token : SmcLexer.Token) PushStart {} Default PushError { error("\"push\" must follow a '/'.", ctxt.getLineNumber()); }}PushStart{ LEFT_PAREN(token : SmcLexer.Token) PushMap {} Default PushError { error("\"push\" must be followed by a '/'.", ctxt.getLineNumber()); }}PushError{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {} LEFT_BRACE(token : SmcLexer.Token) ActionEnd/push(ActionMap::Start) { createActionList(); } Default nil {}}PushMap{ WORD(token : SmcLexer.Token) PushEnd { setPushState(token.getValue()); } Default PushError { error("Expecting a state name.", ctxt.getLineNumber()); }}PushEnd{ RIGHT_PAREN(token : SmcLexer.Token) ActionStart {}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -