view Implab/Automaton/DFAutomaton.cs @ 164:ec35731ae299 ref20160224

Almost complete DFA refactoring
author cin
date Thu, 25 Feb 2016 02:11:13 +0300
parents 0526412bbb26
children
line wrap: on
line source

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;
        }
    }
}