163
|
1 using System;
|
|
2 using System.Collections.Generic;
|
|
3 using System.Linq;
|
|
4
|
|
5 namespace Implab.Automaton {
|
|
6 public class MapAlphabet<T> : IAlphabetBuilder<T> {
|
|
7 readonly Dictionary<T,int> m_map;
|
171
|
8 int m_nextCls;
|
|
9 readonly bool m_supportUnclassified;
|
164
|
10
|
171
|
11 public MapAlphabet(bool supportUnclassified, IEqualityComparer<T> comparer) {
|
|
12 m_map = comparer != null ? new Dictionary<T, int>(comparer) : new Dictionary<T,int>();
|
|
13 m_supportUnclassified = supportUnclassified;
|
|
14 m_nextCls = supportUnclassified ? 1 : 0;
|
163
|
15 }
|
|
16
|
|
17 #region IAlphabetBuilder implementation
|
|
18
|
|
19 public int DefineSymbol(T symbol) {
|
|
20 int cls;
|
171
|
21 return m_map.TryGetValue(symbol, out cls) ? cls : DefineSymbol(symbol, m_nextCls);
|
|
22 }
|
163
|
23
|
171
|
24 public int DefineSymbol(T symbol, int cls) {
|
|
25 Safe.ArgumentAssert(cls >= 0, "cls");
|
163
|
26
|
171
|
27 m_nextCls = Math.Max(cls + 1, m_nextCls);
|
163
|
28 m_map.Add(symbol, cls);
|
|
29 return cls;
|
|
30 }
|
|
31
|
|
32 public int DefineClass(IEnumerable<T> symbols) {
|
171
|
33 return DefineClass(symbols, m_nextCls);
|
|
34 }
|
|
35
|
|
36 public int DefineClass(IEnumerable<T> symbols, int cls) {
|
|
37 Safe.ArgumentAssert(cls >= 0, "cls");
|
163
|
38 Safe.ArgumentNotNull(symbols, "symbols");
|
171
|
39
|
|
40 m_nextCls = Math.Max(cls + 1, m_nextCls);
|
163
|
41
|
171
|
42 foreach (var symbol in symbols)
|
|
43 m_map[symbol] = cls;
|
|
44 return cls;
|
163
|
45 }
|
|
46
|
|
47 #endregion
|
|
48
|
|
49 #region IAlphabet implementation
|
|
50
|
171
|
51 public int Translate(T symbol) {
|
163
|
52 int cls;
|
171
|
53 if (m_map.TryGetValue(symbol, out cls))
|
|
54 return cls;
|
|
55 if (!m_supportUnclassified)
|
|
56 throw new ArgumentOutOfRangeException("symbol", "The specified symbol isn't in the alphabet");
|
|
57 return DFAConst.UNCLASSIFIED_INPUT;
|
163
|
58 }
|
|
59
|
|
60 public int Count {
|
|
61 get {
|
|
62 return m_nextCls;
|
|
63 }
|
|
64 }
|
|
65
|
171
|
66 public bool Contains(T symbol) {
|
|
67 return m_supportUnclassified || m_map.ContainsKey(symbol);
|
|
68 }
|
|
69
|
172
|
70
|
|
71 public IEnumerable<T> GetSymbols(int cls) {
|
|
72 return m_map.Where(p => p.Value == cls).Select(p => p.Key);
|
|
73 }
|
163
|
74 #endregion
|
|
75 }
|
|
76 }
|
|
77
|