diff Implab/Automaton/DFAutomaton.cs @ 162:0526412bbb26 ref20160224

DFA refactoring
author cin
date Wed, 24 Feb 2016 08:39:53 +0300
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Automaton/DFAutomaton.cs	Wed Feb 24 08:39:53 2016 +0300
@@ -0,0 +1,61 @@
+using Implab;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Implab.Automaton {
+    public abstract class DFAutomaton<T> {
+        protected struct ContextFrame {
+            public DFAStateDescriptior[] states;
+            public int current;
+            public T info;
+        }
+
+        public const int INITIAL_STATE = DFADefinition.INITIAL_STATE;
+        public const int UNREACHEBLE_STATE = DFADefinition.UNREACHEBLE_STATE;
+
+        protected ContextFrame m_context;
+        Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
+
+        protected int Level {
+            get { return m_contextStack.Count; }
+        }
+
+        protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
+            Safe.ArgumentNotNull(states, "states");
+            Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
+ 
+            m_context.states = states;
+            m_context.current = startState;
+            m_context.info = info;
+        }
+
+        protected void Switch(DFAStateDescriptior[] states, int current, T info) {
+            Debug.Assert(states != null);
+            Debug.Assert(current >= 0 && current < states.Length);
+            m_contextStack.Push(m_context);
+            m_context.states = states;
+            m_context.current = current;
+            m_context.info = info;
+        }
+
+        protected void Restore() {
+            Debug.Assert(m_contextStack.Count > 0);
+
+            m_context = m_contextStack.Pop();
+        }
+
+        protected void Move(int input) {
+            Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
+            m_context.current = m_context.states[m_context.current].transitions[input];
+        }
+
+        protected bool CanMove(int input) {
+            Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
+            return m_context.states[m_context.current].transitions[input] != UNREACHEBLE_STATE;
+        }
+    }
+}