/// <summary> /// Main DSL code file parser. Uses the Parser state machine to read the code file and process the program. /// </summary> /// <param name="content">text containing DSL program code</param> /// <returns>StateMachine</returns> private StateMachine ParseDSL(string content) { StateMachine stateMachine = null; State currentState = null; Command command = null; Event anEvent = null; State state = null; Transition transition = null; // Encode strings before parsing. content = Utility.PreProcess(content); string separators = " \r\n\t"; string[] tokens = content.Split(separators.ToCharArray()); foreach (string token in tokens) { // Decode strings from token. string tokenValue = Utility.PostProcess(token); string tokenLwr = tokenValue.ToLower(); // Pass the token to our state machine to handle. bool handled = _controller.Handle(tokenLwr); if (!handled && tokenLwr.Length > 0) { // Process the token under our current state. switch (_controller.CurrentState.Name) { case "waitingForCommand": { // Read a Command Name. command = new Command(); command.Name = tokenValue; // Move state to read Command Code. _controller.Handle(_startCode); break; } case "waitingForCommandCode": { // Read a Command Code. command.Code = tokenValue; _commandList.Add(command.Name, command); // Move state back to read Command Name. _controller.Handle(_endCode); break; } case "waitingForEvent": { // Read an Event Name. anEvent = new Event(); anEvent.Name = tokenValue; // Move state to read an Event Code. _controller.Handle(_startCode); break; } case "waitingForEventCode": { // Read an Event Code. anEvent.Code = tokenValue; _eventList.Add(anEvent.Name, anEvent); // Move state back to read an Event Name. _controller.Handle(_endCode); break; } case "waitingForState": { // Read a State Name, stay in this state until next command read. state = new State(tokenValue); currentState = state; _stateList.Add(tokenValue, state); break; } case "waitingForAction": { // Read an Action Name. state.AddAction(_commandList[tokenValue]); // Move state back to reading a State. _controller.Handle(_endCode); break; } case "waitingForTransition": { // Read a Transition Trigger, stay in this state until symbol read for transition Target. transition = new Transition(); transition.Source = currentState; transition.Trigger = _eventList[tokenValue]; break; } case "waitingForTransitionState": { // Read a Transition Target, if the target state is known, assign it now. Otherwise, store it in the symbol table for mapping later. if (_stateList.ContainsKey(tokenValue)) { transition.Target = _stateList[tokenValue]; currentState.AddTransition(transition.Trigger, transition.Target); } else { // Add reference to bind later. _symbolTableForStateList.Add(new Utility.SymbolTableForState(currentState, transition, "Target", _stateList, tokenValue)); } // Move state back to reading a Transition. _controller.Handle(_endCode); break; } } } } // Resolve any references to unknown states. Utility.ResolveReferences(_symbolTableForStateList); // Create the state machine with the starting state. stateMachine = new StateMachine(_stateList["idle"]); return stateMachine; }
public void AddAction(Command action) { _actions.Add(action); }