comparison Implab/Automaton/IndexedAlphabetBase.cs @ 176:0c3c69fe225b ref20160224

rewritten the text scanner
author cin
date Tue, 22 Mar 2016 18:58:40 +0300
parents 92d5278d1b10
children c32688129f14
comparison
equal deleted inserted replaced
175:96a89dcb4060 176:0c3c69fe225b
11 /// <remarks> 11 /// <remarks>
12 /// Indexed alphabets are usefull in bulting efficient translations from source alphabet 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 13 /// to the input alphabet of the automaton. It's assumed that the index to the symbol match
14 /// is well known and documented. 14 /// is well known and documented.
15 /// </remarks> 15 /// </remarks>
16 public abstract class IndexedAlphabetBase<T> : IAlphabetBuilder<T> { 16 public abstract class IndexedAlphabetBase<T> : MapAlphabet<T> {
17 int m_nextId = 1;
18 readonly int[] m_map;
19 17
20 protected IndexedAlphabetBase(int mapSize) { 18 protected IndexedAlphabetBase() :base(true, null) {
21 m_map = new int[mapSize];
22 }
23
24 protected IndexedAlphabetBase(int[] map) {
25 Debug.Assert(map != null && map.Length > 0);
26 Debug.Assert(map.All(x => x >= 0));
27
28 m_map = map;
29 m_nextId = map.Max() + 1;
30 }
31
32 public int DefineSymbol(T symbol) {
33 var index = GetSymbolIndex(symbol);
34 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT)
35 m_map[index] = m_nextId++;
36 return m_map[index];
37 }
38
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
46 public int DefineClass(IEnumerable<T> symbols) {
47 return DefineClass(symbols, m_nextId);
48 }
49
50 public int DefineClass(IEnumerable<T> symbols, int cls) {
51 Safe.ArgumentNotNull(symbols, "symbols");
52 symbols = symbols.Distinct();
53
54 foreach (var symbol in symbols)
55 m_map[GetSymbolIndex(symbol)] = cls;
56
57 m_nextId = Math.Max(cls + 1, m_nextId);
58
59 return cls;
60 }
61
62 public virtual int Translate(T symbol) {
63 return m_map[GetSymbolIndex(symbol)];
64 }
65
66 public int Count {
67 get { return m_nextId; }
68 }
69
70 public bool Contains(T symbol) {
71 return true;
72 }
73
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 } 19 }
79 20
80 public abstract int GetSymbolIndex(T symbol); 21 public abstract int GetSymbolIndex(T symbol);
81 22
82 public abstract T GetSymbolByIndex(int index);
83
84 public abstract IEnumerable<T> InputSymbols { get; }
85
86 /// <summary> 23 /// <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. 24 /// 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> 25 /// </summary>
26 /// <remarks>
27 /// The map is continous and start from the symbol with zero code. The last symbol
28 /// in the map is the last classified symbol in the alphabet, i.e. the map can be
29 /// shorter then the whole alphabet.
30 /// </remarks>
89 /// <returns>The translation map.</returns> 31 /// <returns>The translation map.</returns>
90 public int[] GetTranslationMap() { 32 public int[] GetTranslationMap() {
91 return m_map; 33 Dictionary<int,int> map = new Dictionary<int, int>();
34
35 int max;
36 foreach (var p in Mappings) {
37 var index = GetSymbolIndex(p.Key);
38 max = Math.Max(max, index);
39 map[index] = p.Value;
40 }
41
42 var result = new int[max + 1];
43
44 for (int i = 0; i < result.Length; i++)
45 map.TryGetValue(i, out result[i]);
46
47 return result;
92 } 48 }
93 } 49 }
94 } 50 }