Mercurial > pub > ImplabNet
comparison Implab/Automaton/RegularExpressions/RegularDFABuilder.cs @ 165:e227e78d72e4 ref20160224
DFA refactoring
author | cin |
---|---|
date | Mon, 29 Feb 2016 02:02:17 +0300 |
parents | ec35731ae299 |
children | 181119ef3b39 |
comparison
equal
deleted
inserted
replaced
164:ec35731ae299 | 165:e227e78d72e4 |
---|---|
9 /// Используется для построения ДКА по регулярному выражению, сначала обходит | 9 /// Используется для построения ДКА по регулярному выражению, сначала обходит |
10 /// регулярное выражение и вычисляет followpos, затем используется метод | 10 /// регулярное выражение и вычисляет followpos, затем используется метод |
11 /// <see cref="BuildDFA(IDFADefinition)"/> для построения автомата. | 11 /// <see cref="BuildDFA(IDFADefinition)"/> для построения автомата. |
12 /// </summary> | 12 /// </summary> |
13 public class RegularDFABuilder<TTag> : IVisitor<TTag> { | 13 public class RegularDFABuilder<TTag> : IVisitor<TTag> { |
14 int m_idx = 0; | 14 int m_idx; |
15 Token<TTag> m_root; | 15 Token<TTag> m_root; |
16 HashSet<int> m_firstpos; | 16 HashSet<int> m_firstpos; |
17 HashSet<int> m_lastpos; | 17 HashSet<int> m_lastpos; |
18 | 18 |
19 readonly Dictionary<int, HashSet<int>> m_followpos = new Dictionary<int, HashSet<int>>(); | 19 readonly Dictionary<int, HashSet<int>> m_followpos = new Dictionary<int, HashSet<int>>(); |
24 get { return m_followpos; } | 24 get { return m_followpos; } |
25 } | 25 } |
26 | 26 |
27 public HashSet<int> Followpos(int pos) { | 27 public HashSet<int> Followpos(int pos) { |
28 HashSet<int> set; | 28 HashSet<int> set; |
29 if (m_followpos.TryGetValue(pos, out set)) | 29 return m_followpos.TryGetValue(pos, out set) ? set : m_followpos[pos] = new HashSet<int>(); |
30 return set; | |
31 return m_followpos[pos] = new HashSet<int>(); | |
32 } | 30 } |
33 | 31 |
34 bool Nullable(object n) { | 32 bool Nullable(object n) { |
35 if (n is EmptyToken<TTag> || n is StarToken<TTag>) | 33 if (n is EmptyToken<TTag> || n is StarToken<TTag>) |
36 return true; | 34 return true; |
37 if (n is AltToken<TTag>) | 35 var altToken = n as AltToken<TTag>; |
38 return Nullable(((AltToken<TTag>)n).Left) || Nullable(((AltToken<TTag>)n).Right); | 36 if (altToken != null) |
39 if (n is CatToken<TTag>) | 37 return Nullable(altToken.Left) || Nullable(altToken.Right); |
40 return Nullable(((CatToken<TTag>)n).Left) && Nullable(((CatToken<TTag>)n).Right); | 38 var catToken = n as CatToken<TTag>; |
39 if (catToken != null) | |
40 return Nullable(catToken.Left) && Nullable(catToken.Right); | |
41 return false; | 41 return false; |
42 } | 42 } |
43 | 43 |
44 | 44 |
45 public void Visit(AltToken<TTag> token) { | 45 public void Visit(AltToken<TTag> token) { |
120 m_lastpos = new HashSet<int>(new[] { m_idx }); | 120 m_lastpos = new HashSet<int>(new[] { m_idx }); |
121 Followpos(m_idx); | 121 Followpos(m_idx); |
122 m_ends.Add(m_idx, token.Tag); | 122 m_ends.Add(m_idx, token.Tag); |
123 } | 123 } |
124 | 124 |
125 public void BuildDFA(IDFATransitionTableBuilder<TTag> dfa) { | 125 public void BuildDFA(IDFATableBuilder<TTag> dfa) { |
126 Safe.ArgumentNotNull(dfa,"dfa"); | 126 Safe.ArgumentNotNull(dfa,"dfa"); |
127 | 127 |
128 var states = new MapAlphabet<HashSet<int>>(new CustomEqualityComparer<HashSet<int>>( | 128 var states = new MapAlphabet<HashSet<int>>(new CustomEqualityComparer<HashSet<int>>( |
129 (x, y) => x.SetEquals(y), | 129 (x, y) => x.SetEquals(y), |
130 x => x.Sum(n => n.GetHashCode()) | 130 x => x.Sum(n => n.GetHashCode()) |