Mercurial > pub > ImplabNet
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; + } + } +}