static void Main(string[] args)
        {
            string command = "";

            // Get application folder.
            string path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            // Setup a state machine by reading the external domain specific language program.
            Parser parser = new Parser();
            StateMachine machine = parser.GetStateMachine(path + "\\dungeon.txt");
            Console.WriteLine("Loading of External DSL completed.\n");

            // Setup controller to run state machine.
            Controller controller = new Controller(machine);

            // Display some help.
            Console.WriteLine("> Q = Quit, ? = Available Commands");
            Console.WriteLine("> Entering the dungeon.");

            // Execute the starting state.
            controller.CurrentState.Execute();

            // Read commands from user to activate state machine.
            while (command.ToLower() != "q")
            {
                Console.Write("> ");

                // Read a command.
                command = Console.ReadLine();

                // Send the command to our state machine.
                HandleCommand(controller, command);
            }
        }
 /// <summary>
 /// Sends the command to the controller to handle.
 /// </summary>
 /// <param name="command">string</param>
 /// <param name="controller">state machine controller</param>
 private static void HandleCommand(Controller controller, string command)
 {
     if (!controller.Handle(command))
     {
         if (command == "?")
         {
             // Display available commands for the given state.
             foreach (string eventCode in controller.CurrentState.GetEventCodes())
             {
                 Console.WriteLine(eventCode);
             }
         }
         else if (command.ToLower() != "q")
         {
             Console.WriteLine("Huh?");
         }
     }
 }
        public Parser()
        {
            // Setup a state machine with an internal DSL to handle parsing our code file.
            // You could actually create an external DSL code file to program the Parser itself, but for this example, we'll just utilize the code with an internal DSL.

            #region Setup Parser State Machine

            // States
            State idle = new State("idle");
            State waitingForCommand = new State("waitingForCommand");
            State waitingForCommandCode = new State("waitingForCommandCode");
            State waitingForEvent = new State("waitingForEvent");
            State waitingForEventCode = new State("waitingForEventCode");
            State waitingForState = new State("waitingForState");
            State waitingForAction = new State("waitingForAction");
            State waitingForTransition = new State("waitingForTransition");
            State waitingForTransitionState = new State("waitingForTransitionState");

            // Events
            Event readCommandStart = new Event("readCommandStart", _commandsToken);
            Event readCommandCodeStart = new Event("readCommandCodeStart", _startCode);
            Event readCommandCodeEnd = new Event("readCommandCodeEnd", _endCode);

            Event readEventStart = new Event("readEventStart", _eventsToken);
            Event readEventCodeStart = new Event("readEventCodeStart", _startCode);
            Event readEventCodeEnd = new Event("readEventCodeEnd", _endCode);

            Event readActionStart = new Event("readActionStart", _actionsToken);
            Event readActionEnd = new Event("readActionEnd", _endCode);

            Event readStateStart = new Event("readStateStart", _stateToken);

            Event readTransitionStart = new Event("readTransitionEvent", _transitionsToken);
            Event readTransitionState = new Event("readTransitionState", "=>");
            Event readTransitionStateEnd = new Event("readTransitionStateEnd", _endCode);
            Event endTransition = new Event("endTransition", ".");

            Event resetEvent = new Event("resetEvent", _resetToken);

            // Transitions
            idle.AddTransition(readCommandStart, waitingForCommand);
            idle.AddTransition(readEventStart, waitingForEvent);
            idle.AddTransition(readStateStart, waitingForState);

            waitingForCommand.AddTransition(readCommandCodeStart, waitingForCommandCode);
            waitingForCommandCode.AddTransition(readCommandCodeEnd, waitingForCommand);

            waitingForEvent.AddTransition(readEventCodeStart, waitingForEventCode);
            waitingForEventCode.AddTransition(readEventCodeEnd, waitingForEvent);

            waitingForState.AddTransition(readActionStart, waitingForAction);
            waitingForState.AddTransition(readTransitionStart, waitingForTransition);

            waitingForAction.AddTransition(readActionEnd, waitingForState);

            waitingForTransition.AddTransition(readTransitionState, waitingForTransitionState);
            waitingForTransition.AddTransition(endTransition, waitingForState);
            waitingForTransitionState.AddTransition(readTransitionStateEnd, waitingForTransition);

            // Setup state machine.
            _stateMachine = new StateMachine(idle);

            _stateMachine.AddResetEvent(resetEvent);

            // Setup controller.
            _controller = new Controller(_stateMachine);

            #endregion
        }