162
|
1 using Implab;
|
|
2 using System;
|
|
3 using System.Collections.Generic;
|
|
4 using System.Diagnostics;
|
|
5 using System.Linq;
|
|
6
|
|
7 namespace Implab.Automaton {
|
|
8 /// <summary>
|
|
9 /// Indexed alphabet is the finite set of symbols where each symbol has a zero-based unique index.
|
|
10 /// </summary>
|
167
|
11 /// <remarks>
|
|
12 /// Indexed alphabets are usefull in bulting efficient translations from source alphabet
|
|
13 /// to the input alphabet of the automaton. It's assumed that the index to the symbol match
|
|
14 /// is well known and documented.
|
|
15 /// </remarks>
|
162
|
16 public abstract class IndexedAlphabetBase<T> : IAlphabetBuilder<T> {
|
|
17 int m_nextId = 1;
|
|
18 readonly int[] m_map;
|
|
19
|
|
20 protected IndexedAlphabetBase(int mapSize) {
|
|
21 m_map = new int[mapSize];
|
|
22 }
|
|
23
|
|
24 protected IndexedAlphabetBase(int[] map) {
|
171
|
25 Debug.Assert(map != null && map.Length > 0);
|
|
26 Debug.Assert(map.All(x => x >= 0));
|
162
|
27
|
|
28 m_map = map;
|
|
29 m_nextId = map.Max() + 1;
|
|
30 }
|
|
31
|
|
32 public int DefineSymbol(T symbol) {
|
|
33 var index = GetSymbolIndex(symbol);
|
164
|
34 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT)
|
162
|
35 m_map[index] = m_nextId++;
|
|
36 return m_map[index];
|
|
37 }
|
|
38
|
171
|
39 public int DefineSymbol(T symbol, int cls) {
|
|
40 var index = GetSymbolIndex(symbol);
|
|
41 m_map[index] = cls;
|
|
42 m_nextId = Math.Max(cls + 1, m_nextId);
|
|
43 return cls;
|
|
44 }
|
|
45
|
162
|
46 public int DefineClass(IEnumerable<T> symbols) {
|
171
|
47 return DefineClass(symbols, m_nextId);
|
|
48 }
|
|
49
|
|
50 public int DefineClass(IEnumerable<T> symbols, int cls) {
|
162
|
51 Safe.ArgumentNotNull(symbols, "symbols");
|
|
52 symbols = symbols.Distinct();
|
|
53
|
171
|
54 foreach (var symbol in symbols)
|
|
55 m_map[GetSymbolIndex(symbol)] = cls;
|
|
56
|
|
57 m_nextId = Math.Max(cls + 1, m_nextId);
|
162
|
58
|
171
|
59 return cls;
|
162
|
60 }
|
|
61
|
|
62 public virtual int Translate(T symbol) {
|
|
63 return m_map[GetSymbolIndex(symbol)];
|
|
64 }
|
|
65
|
171
|
66 public int Count {
|
|
67 get { return m_nextId; }
|
|
68 }
|
|
69
|
|
70 public bool Contains(T symbol) {
|
|
71 return true;
|
|
72 }
|
|
73
|
172
|
74 public IEnumerable<T> GetSymbols(int cls) {
|
|
75 for (var i = 0; i < m_map.Length; i++)
|
|
76 if (m_map[i] == cls)
|
|
77 yield return GetSymbolByIndex(i);
|
|
78 }
|
|
79
|
162
|
80 public abstract int GetSymbolIndex(T symbol);
|
|
81
|
172
|
82 public abstract T GetSymbolByIndex(int index);
|
|
83
|
162
|
84 public abstract IEnumerable<T> InputSymbols { get; }
|
|
85
|
|
86 /// <summary>
|
|
87 /// Gets the translation map from the index of the symbol to it's class this is usefull for the optimized input symbols transtaion.
|
|
88 /// </summary>
|
|
89 /// <returns>The translation map.</returns>
|
|
90 public int[] GetTranslationMap() {
|
|
91 return m_map;
|
|
92 }
|
|
93 }
|
|
94 }
|