55
|
1 using Implab;
|
|
2 using System;
|
|
3 using System.Collections.Generic;
|
|
4 using System.Diagnostics;
|
|
5 using System.Linq;
|
|
6 using System.Text;
|
|
7 using System.Threading.Tasks;
|
|
8
|
|
9 namespace Implab.Parsing {
|
|
10 public abstract class DFAutomaton<T> {
|
|
11 protected struct ContextFrame {
|
|
12 public DFAStateDescriptior[] states;
|
|
13 public int current;
|
|
14 public T info;
|
|
15 }
|
|
16
|
|
17 public const int INITIAL_STATE = DFADefinitionBase.INITIAL_STATE;
|
|
18 public const int UNREACHEBLE_STATE = DFADefinitionBase.UNREACHEBLE_STATE;
|
|
19
|
|
20 protected ContextFrame m_context;
|
|
21 Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
|
|
22
|
|
23 public int Level {
|
|
24 get { return m_contextStack.Count; }
|
|
25 }
|
|
26
|
|
27 protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
|
|
28 Safe.ArgumentNotNull(states, "states");
|
|
29 Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
|
|
30
|
|
31 m_context.states = states;
|
|
32 m_context.current = startState;
|
|
33 m_context.info = info;
|
|
34 }
|
|
35
|
|
36 protected void Switch(DFAStateDescriptior[] states, int current, T info) {
|
|
37 Debug.Assert(states != null);
|
|
38 Debug.Assert(current >= 0 && current < states.Length);
|
|
39 m_contextStack.Push(m_context);
|
|
40 m_context. states = states;
|
|
41 m_context.current = current;
|
|
42 m_context.info = info;
|
|
43 }
|
|
44
|
|
45 protected void Restore() {
|
|
46 Debug.Assert(m_contextStack.Count > 0);
|
|
47
|
|
48 m_context = m_contextStack.Pop();
|
|
49 }
|
|
50
|
|
51 protected void Move(int input) {
|
|
52 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
|
|
53 m_context.current = m_context.states[m_context.current].transitions[input];
|
|
54 }
|
|
55 }
|
|
56 }
|