228
|
1 using Implab.Automaton;
|
|
2 using System;
|
|
3 using System.Collections.Generic;
|
|
4 using System.Linq;
|
|
5 using System.Text;
|
|
6 using System.Threading.Tasks;
|
|
7
|
|
8 namespace Implab.Formats {
|
|
9 public class InputScanner<TTag> {
|
|
10 readonly TTag[] m_tags;
|
|
11 readonly int m_initialState;
|
|
12 readonly int[,] m_dfa;
|
|
13 readonly CharMap m_alphabet;
|
|
14 readonly bool[] m_final;
|
|
15
|
|
16 int m_position;
|
|
17 int m_state;
|
|
18
|
|
19 public InputScanner(int[,] dfaTable, bool[] finalStates, TTag[] tags, int initialState, CharMap alphabet) {
|
|
20 Safe.ArgumentNotNull(dfaTable, nameof(dfaTable));
|
|
21 Safe.ArgumentNotNull(finalStates, nameof(finalStates));
|
|
22 Safe.ArgumentNotNull(tags, nameof(tags));
|
|
23 Safe.ArgumentNotNull(alphabet, nameof(alphabet));
|
|
24
|
|
25 m_dfa = dfaTable;
|
|
26 m_final = finalStates;
|
|
27 m_tags = tags;
|
|
28 m_initialState = initialState;
|
|
29 m_alphabet = alphabet;
|
|
30 }
|
|
31
|
|
32 public TTag Tag {
|
|
33 get {
|
|
34 return m_tags[m_state];
|
|
35 }
|
|
36 }
|
|
37
|
|
38 public int Position {
|
|
39 get {
|
|
40 return m_position;
|
|
41 }
|
|
42 }
|
|
43
|
|
44 public bool IsFinal {
|
|
45 get {
|
|
46 return m_final[m_state];
|
|
47 }
|
|
48 }
|
|
49
|
|
50 public void Reset() {
|
|
51 m_state = m_initialState;
|
|
52 }
|
|
53
|
|
54 public InputScanner<TTag> Clone() {
|
|
55 var clone = new InputScanner<TTag>(m_dfa, m_final, m_tags, m_initialState, m_alphabet);
|
|
56 clone.m_state = m_state;
|
|
57 clone.m_position = m_position;
|
|
58 return clone;
|
|
59 }
|
|
60
|
|
61 public bool Scan(char[] data, int offset, int length) {
|
|
62 if (length <= 0) {
|
|
63 m_position = offset;
|
|
64 return false; // EOF
|
|
65 }
|
|
66
|
|
67 var max = offset + length;
|
|
68 var next = m_state;
|
|
69
|
|
70 while(offset < max) {
|
|
71 next = m_dfa[next, m_alphabet.Translate(data[offset])];
|
|
72 if (next == AutomatonConst.UNREACHABLE_STATE) {
|
|
73 // scanner stops on the next position after last recognized symbol
|
|
74 m_position = offset;
|
|
75 return false;
|
|
76 }
|
|
77 m_state = next;
|
|
78 offset++;
|
|
79 }
|
|
80 m_position = offset;
|
|
81 return true;
|
|
82 }
|
|
83 }
|
|
84 }
|