##// END OF EJS Templates
Working on text scanner
cin -
r172:92d5278d1b10 ref20160224
parent child
Show More
@@ -0,0 +1,8
1 using System;
2
3 namespace Implab.Automaton.RegularExpressions {
4 public interface ITaggedDFABuilder<TTag> : IDFATableBuilder {
5 void SetStateTag(int s, TTag[] tags);
6 }
7 }
8
@@ -0,0 +1,89
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace Implab.Automaton.RegularExpressions {
6 public class RegularDFA<TInput, TTag> : DFATable, ITaggedDFABuilder<TTag> {
7
8 readonly Dictionary<int,TTag[]> m_tags = new Dictionary<int, TTag[]>();
9 readonly IAlphabet<TInput> m_alphabet;
10
11 public RegularDFA(IAlphabet<TInput> alphabet) {
12 Safe.ArgumentNotNull(alphabet, "aplhabet");
13
14 m_alphabet = alphabet;
15 }
16
17
18 public IAlphabet<TInput> InputAlphabet {
19 get {
20 return m_alphabet;
21 }
22 }
23
24 public void MarkFinalState(int s, TTag[] tags) {
25 MarkFinalState(s);
26 SetStateTag(s, tags);
27 }
28
29 public void SetStateTag(int s, TTag[] tags) {
30 Safe.ArgumentNotNull(tags, "tags");
31 m_tags[s] = tags;
32 }
33
34 public TTag[] GetStateTag(int s) {
35 TTag[] tags;
36 return m_tags.TryGetValue(s, out tags) ? tags : new TTag[0];
37 }
38
39 public new DFAStateDescriptor<TTag>[] CreateTransitionTable() {
40 var table = new DFAStateDescriptor<TTag>[StateCount];
41
42 foreach (var t in this) {
43 if (table[t.s1].transitions == null)
44 table[t.s1] = new DFAStateDescriptor<TTag>(AlphabetSize, IsFinalState(t.s1), GetStateTag(t.s1));
45 if (table[t.s2].transitions == null)
46 table[t.s2] = new DFAStateDescriptor<TTag>(AlphabetSize, IsFinalState(t.s2), GetStateTag(t.s2));
47 table[t.s1].transitions[t.edge] = t.s2;
48 }
49
50 return table;
51 }
52
53 /// <summary>
54 /// Optimize the specified alphabet.
55 /// </summary>
56 /// <param name="alphabet">Пустой алфавит, который будет зполнен в процессе оптимизации.</param>
57 public RegularDFA<TInput,TTag> Optimize(IAlphabetBuilder<TInput> alphabet) {
58 Safe.ArgumentNotNull(alphabet, "alphabet");
59
60 var dfa = new RegularDFA<TInput, TTag>(alphabet);
61
62 var states = new DummyAlphabet(StateCount);
63 var alphaMap = new Dictionary<int,int>();
64 var stateMap = new Dictionary<int,int>();
65
66 Optimize(dfa, alphaMap, stateMap);
67
68 // mark tags in the new DFA
69 foreach (var g in m_tags.Where(x => x.Key < StateCount).GroupBy(x => stateMap[x.Key], x => x.Value ))
70 dfa.SetStateTag(g.Key, g.SelectMany(x => x).ToArray());
71
72 // make the alphabet for the new DFA
73 foreach (var pair in alphaMap)
74 alphabet.DefineClass(m_alphabet.GetSymbols(pair.Key), pair.Value);
75
76 return dfa;
77 }
78
79 protected override IEnumerable<HashSet<int>> GroupFinalStates() {
80 var arrayComparer = new CustomEqualityComparer<TTag[]>(
81 (x,y) => x.Length == y.Length && x.All(it => y.Contains(it)),
82 x => x.Sum(it => x.GetHashCode())
83 );
84 return FinalStates.GroupBy(x => m_tags[x], arrayComparer).Select(g => new HashSet<int>(g));
85 }
86
87 }
88 }
89
@@ -0,0 +1,184
1 using Implab;
2 using System;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Linq;
6
7 namespace Implab.Automaton.RegularExpressions {
8 /// <summary>
9 /// Используется для построения ДКА по регулярному выражению, сначала обходит
10 /// регулярное выражение и вычисляет followpos, затем используется метод
11 /// <see cref="BuildDFA(IDFADefinition)"/> для построения автомата.
12 /// </summary>
13 public class RegularExpressionVisitor<TTag> : IVisitor<TTag> {
14 int m_idx;
15 Token<TTag> m_root;
16 HashSet<int> m_firstpos;
17 HashSet<int> m_lastpos;
18
19 readonly Dictionary<int, HashSet<int>> m_followpos = new Dictionary<int, HashSet<int>>();
20 readonly Dictionary<int, int> m_indexes = new Dictionary<int, int>();
21 readonly Dictionary<int, TTag> m_ends = new Dictionary<int, TTag>();
22
23 public Dictionary<int, HashSet<int>> FollowposMap {
24 get { return m_followpos; }
25 }
26
27 public HashSet<int> Followpos(int pos) {
28 HashSet<int> set;
29 return m_followpos.TryGetValue(pos, out set) ? set : m_followpos[pos] = new HashSet<int>();
30 }
31
32 bool Nullable(object n) {
33 if (n is EmptyToken<TTag> || n is StarToken<TTag>)
34 return true;
35 var altToken = n as AltToken<TTag>;
36 if (altToken != null)
37 return Nullable(altToken.Left) || Nullable(altToken.Right);
38 var catToken = n as CatToken<TTag>;
39 if (catToken != null)
40 return Nullable(catToken.Left) && Nullable(catToken.Right);
41 return false;
42 }
43
44
45 public void Visit(AltToken<TTag> token) {
46 if (m_root == null)
47 m_root = token;
48 var firtspos = new HashSet<int>();
49 var lastpos = new HashSet<int>();
50
51 token.Left.Accept(this);
52 firtspos.UnionWith(m_firstpos);
53 lastpos.UnionWith(m_lastpos);
54
55 token.Right.Accept(this);
56 firtspos.UnionWith(m_firstpos);
57 lastpos.UnionWith(m_lastpos);
58
59 m_firstpos = firtspos;
60 m_lastpos = lastpos;
61 }
62
63 public void Visit(StarToken<TTag> token) {
64 if (m_root == null)
65 m_root = token;
66 token.Token.Accept(this);
67
68 foreach (var i in m_lastpos)
69 Followpos(i).UnionWith(m_firstpos);
70 }
71
72 public void Visit(CatToken<TTag> token) {
73 if (m_root == null)
74 m_root = token;
75
76 var firtspos = new HashSet<int>();
77 var lastpos = new HashSet<int>();
78 token.Left.Accept(this);
79 firtspos.UnionWith(m_firstpos);
80 var leftLastpos = m_lastpos;
81
82 token.Right.Accept(this);
83 lastpos.UnionWith(m_lastpos);
84 var rightFirstpos = m_firstpos;
85
86 if (Nullable(token.Left))
87 firtspos.UnionWith(rightFirstpos);
88
89 if (Nullable(token.Right))
90 lastpos.UnionWith(leftLastpos);
91
92 m_firstpos = firtspos;
93 m_lastpos = lastpos;
94
95 foreach (var i in leftLastpos)
96 Followpos(i).UnionWith(rightFirstpos);
97
98 }
99
100 public void Visit(EmptyToken<TTag> token) {
101 if (m_root == null)
102 m_root = token;
103 }
104
105 public void Visit(SymbolToken<TTag> token) {
106 if (m_root == null)
107 m_root = token;
108 m_idx++;
109 m_indexes[m_idx] = token.Value;
110 m_firstpos = new HashSet<int>(new[] { m_idx });
111 m_lastpos = new HashSet<int>(new[] { m_idx });
112 }
113
114 public void Visit(EndToken<TTag> token) {
115 if (m_root == null)
116 m_root = token;
117 m_idx++;
118 m_indexes[m_idx] = DFAConst.UNCLASSIFIED_INPUT;
119 m_firstpos = new HashSet<int>(new[] { m_idx });
120 m_lastpos = new HashSet<int>(new[] { m_idx });
121 Followpos(m_idx);
122 m_ends.Add(m_idx, token.Tag);
123 }
124
125 public void BuildDFA(ITaggedDFABuilder<TTag> dfa) {
126 Safe.ArgumentNotNull(dfa,"dfa");
127
128 var states = new MapAlphabet<HashSet<int>>(
129 false,
130 new CustomEqualityComparer<HashSet<int>>(
131 (x, y) => x.SetEquals(y),
132 x => x.Sum(n => n.GetHashCode())
133 ));
134
135 var initialState = states.DefineSymbol(m_firstpos);
136 dfa.SetInitialState(initialState);
137
138 var tags = GetStateTags(m_firstpos);
139 if (tags != null && tags.Length > 0)
140 dfa.MarkFinalState(initialState, tags);
141
142 var inputMax = m_indexes.Values.Max();
143 var queue = new Queue<HashSet<int>>();
144
145 queue.Enqueue(m_firstpos);
146
147 while (queue.Count > 0) {
148 var state = queue.Dequeue();
149 var s1 = states.Translate(state);
150 Debug.Assert(s1 != DFAConst.UNCLASSIFIED_INPUT);
151
152 for (int a = 0; a <= inputMax; a++) {
153 var next = new HashSet<int>();
154 foreach (var p in state) {
155 if (m_indexes[p] == a) {
156 next.UnionWith(Followpos(p));
157 }
158 }
159 if (next.Count > 0) {
160 int s2 = states.Translate(next);
161 if (s2 == DFAConst.UNCLASSIFIED_INPUT) {
162 s2 = states.DefineSymbol(next);
163
164 tags = GetStateTags(next);
165 if (tags != null && tags.Length > 0) {
166 dfa.MarkFinalState(s2);
167 dfa.SetStateTag(s2, tags);
168 }
169
170 queue.Enqueue(next);
171 }
172 dfa.Add(new AutomatonTransition(s1, s2, a));
173 }
174 }
175 }
176 }
177
178 TTag[] GetStateTags(IEnumerable<int> state) {
179 Debug.Assert(state != null);
180 return state.Where(m_ends.ContainsKey).Select(pos => m_ends[pos]).ToArray();
181 }
182
183 }
184 }
@@ -1,26 +1,26
1 namespace Implab.Automaton {
1 namespace Implab.Automaton {
2 public struct DFAStateDescriptior {
2 public struct DFAStateDescriptor {
3 public readonly bool final;
3 public readonly bool final;
4 public readonly int[] transitions;
4 public readonly int[] transitions;
5
5
6
6
7 public DFAStateDescriptior(int[] transitions, bool final) {
7 public DFAStateDescriptor(int[] transitions, bool final) {
8 this.transitions = transitions;
8 this.transitions = transitions;
9 this.final = final;
9 this.final = final;
10 }
10 }
11
11
12 public DFAStateDescriptior(int[] transitions) : this(transitions, false) {
12 public DFAStateDescriptor(int[] transitions) : this(transitions, false) {
13 }
13 }
14
14
15 public DFAStateDescriptior(int size, bool final) {
15 public DFAStateDescriptor(int size, bool final) {
16 Safe.ArgumentInRange(size, 0, int.MaxValue, "size");
16 Safe.ArgumentInRange(size, 0, int.MaxValue, "size");
17
17
18 this.final = final;
18 this.final = final;
19
19
20 transitions = new int[size];
20 transitions = new int[size];
21
21
22 for (int i = 0; i < size; i++)
22 for (int i = 0; i < size; i++)
23 transitions[i] = DFAConst.UNREACHABLE_STATE;
23 transitions[i] = DFAConst.UNREACHABLE_STATE;
24 }
24 }
25 }
25 }
26 }
26 }
@@ -1,291 +1,305
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Linq;
4 using System.Linq;
5
5
6 namespace Implab.Automaton {
6 namespace Implab.Automaton {
7 public class DFATable : IDFATableBuilder {
7 public class DFATable : IDFATableBuilder {
8 int m_stateCount;
8 int m_stateCount;
9 int m_symbolCount;
9 int m_symbolCount;
10 int m_initialState;
10 int m_initialState;
11
11
12 readonly HashSet<int> m_finalStates = new HashSet<int>();
12 readonly HashSet<int> m_finalStates = new HashSet<int>();
13 readonly HashSet<AutomatonTransition> m_transitions = new HashSet<AutomatonTransition>();
13 readonly HashSet<AutomatonTransition> m_transitions = new HashSet<AutomatonTransition>();
14
14
15
15
16 #region IDFADefinition implementation
16 #region IDFADefinition implementation
17
17
18 public bool IsFinalState(int s) {
18 public bool IsFinalState(int s) {
19 Safe.ArgumentInRange(s, 0, m_stateCount, "s");
19 Safe.ArgumentInRange(s, 0, m_stateCount, "s");
20
20
21 return m_finalStates.Contains(s);
21 return m_finalStates.Contains(s);
22 }
22 }
23
23
24 public IEnumerable<int> FinalStates {
24 public IEnumerable<int> FinalStates {
25 get {
25 get {
26 return m_finalStates;
26 return m_finalStates;
27 }
27 }
28 }
28 }
29
29
30 public int StateCount {
30 public int StateCount {
31 get { return m_stateCount; }
31 get { return m_stateCount; }
32 }
32 }
33
33
34 public int AlphabetSize {
34 public int AlphabetSize {
35 get { return m_symbolCount; }
35 get { return m_symbolCount; }
36 }
36 }
37
37
38 public int InitialState {
38 public int InitialState {
39 get { return m_initialState; }
39 get { return m_initialState; }
40 }
40 }
41
41
42 #endregion
42 #endregion
43
43
44 public void SetInitialState(int s) {
44 public void SetInitialState(int s) {
45 Safe.ArgumentAssert(s >= 0, "s");
45 Safe.ArgumentAssert(s >= 0, "s");
46 m_initialState = s;
46 m_initialState = s;
47 }
47 }
48
48
49 public void MarkFinalState(int state) {
49 public void MarkFinalState(int state) {
50 m_finalStates.Add(state);
50 m_finalStates.Add(state);
51 }
51 }
52
52
53 public void Add(AutomatonTransition item) {
53 public void Add(AutomatonTransition item) {
54 Safe.ArgumentAssert(item.s1 >= 0, "item");
54 Safe.ArgumentAssert(item.s1 >= 0, "item");
55 Safe.ArgumentAssert(item.s2 >= 0, "item");
55 Safe.ArgumentAssert(item.s2 >= 0, "item");
56 Safe.ArgumentAssert(item.edge >= 0, "item");
56 Safe.ArgumentAssert(item.edge >= 0, "item");
57
57
58 m_stateCount = Math.Max(m_stateCount, Math.Max(item.s1, item.s2) + 1);
58 m_stateCount = Math.Max(m_stateCount, Math.Max(item.s1, item.s2) + 1);
59 m_symbolCount = Math.Max(m_symbolCount, item.edge);
59 m_symbolCount = Math.Max(m_symbolCount, item.edge);
60
60
61 m_transitions.Add(item);
61 m_transitions.Add(item);
62 }
62 }
63
63
64 public void Clear() {
64 public void Clear() {
65 m_stateCount = 0;
65 m_stateCount = 0;
66 m_symbolCount = 0;
66 m_symbolCount = 0;
67 m_finalStates.Clear();
67 m_finalStates.Clear();
68 m_transitions.Clear();
68 m_transitions.Clear();
69 }
69 }
70
70
71 public bool Contains(AutomatonTransition item) {
71 public bool Contains(AutomatonTransition item) {
72 return m_transitions.Contains(item);
72 return m_transitions.Contains(item);
73 }
73 }
74
74
75 public void CopyTo(AutomatonTransition[] array, int arrayIndex) {
75 public void CopyTo(AutomatonTransition[] array, int arrayIndex) {
76 m_transitions.CopyTo(array, arrayIndex);
76 m_transitions.CopyTo(array, arrayIndex);
77 }
77 }
78
78
79 public bool Remove(AutomatonTransition item) {
79 public bool Remove(AutomatonTransition item) {
80 m_transitions.Remove(item);
80 m_transitions.Remove(item);
81 }
81 }
82
82
83 public int Count {
83 public int Count {
84 get {
84 get {
85 return m_transitions.Count;
85 return m_transitions.Count;
86 }
86 }
87 }
87 }
88
88
89 public bool IsReadOnly {
89 public bool IsReadOnly {
90 get {
90 get {
91 return false;
91 return false;
92 }
92 }
93 }
93 }
94
94
95 public IEnumerator<AutomatonTransition> GetEnumerator() {
95 public IEnumerator<AutomatonTransition> GetEnumerator() {
96 return m_transitions.GetEnumerator();
96 return m_transitions.GetEnumerator();
97 }
97 }
98
98
99 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
99 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
100 return GetEnumerator();
100 return GetEnumerator();
101 }
101 }
102
102
103 public DFAStateDescriptor[] CreateTransitionTable() {
104 var table = new DFAStateDescriptor[StateCount];
105
106 foreach (var t in this) {
107 if (table[t.s1].transitions == null)
108 table[t.s1] = new DFAStateDescriptor(AlphabetSize, IsFinalState(t.s1));
109 if (table[t.s2].transitions == null)
110 table[t.s2] = new DFAStateDescriptor(AlphabetSize, IsFinalState(t.s2));
111 table[t.s1].transitions[t.edge] = t.s2;
112 }
113
114 return table;
115 }
116
103 /// <summary>Формирует множества конечных состояний перед началом работы алгоритма минимизации.</summary>
117 /// <summary>Формирует множества конечных состояний перед началом работы алгоритма минимизации.</summary>
104 /// <remarks>
118 /// <remarks>
105 /// В процессе построения минимального автомата требуется разделить множество состояний,
119 /// В процессе построения минимального автомата требуется разделить множество состояний,
106 /// на два подмножества - конечные состояния и все остальные, после чего эти подмножества
120 /// на два подмножества - конечные состояния и все остальные, после чего эти подмножества
107 /// будут резделены на более мелкие. Иногда требуется гарантировать различия конечных сосотяний,
121 /// будут резделены на более мелкие. Иногда требуется гарантировать различия конечных сосотяний,
108 /// для этого необходимо переопределить даннцю фукнцию, для получения множеств конечных состояний.
122 /// для этого необходимо переопределить даннцю фукнцию, для получения множеств конечных состояний.
109 /// </remarks>
123 /// </remarks>
110 /// <returns>The final states.</returns>
124 /// <returns>The final states.</returns>
111 protected virtual IEnumerable<HashSet<int>> GroupFinalStates() {
125 protected virtual IEnumerable<HashSet<int>> GroupFinalStates() {
112 return new HashSet<int>[] { m_finalStates };
126 return new HashSet<int>[] { m_finalStates };
113 }
127 }
114
128
115 protected void Optimize(
129 protected void Optimize(
116 IDFATableBuilder optimalDFA,
130 IDFATableBuilder optimalDFA,
117 IDictionary<int,int> alphabetMap,
131 IDictionary<int,int> alphabetMap,
118 IDictionary<int,int> stateMap
132 IDictionary<int,int> stateMap
119 ) {
133 ) {
120 Safe.ArgumentNotNull(optimalDFA, "dfa");
134 Safe.ArgumentNotNull(optimalDFA, "dfa");
121 Safe.ArgumentNotNull(alphabetMap, "alphabetMap");
135 Safe.ArgumentNotNull(alphabetMap, "alphabetMap");
122 Safe.ArgumentNotNull(stateMap, "stateMap");
136 Safe.ArgumentNotNull(stateMap, "stateMap");
123
137
124
138
125 var setComparer = new CustomEqualityComparer<HashSet<int>>(
139 var setComparer = new CustomEqualityComparer<HashSet<int>>(
126 (x, y) => x.SetEquals(y),
140 (x, y) => x.SetEquals(y),
127 s => s.Sum(x => x.GetHashCode())
141 s => s.Sum(x => x.GetHashCode())
128 );
142 );
129
143
130 var optimalStates = new HashSet<HashSet<int>>(setComparer);
144 var optimalStates = new HashSet<HashSet<int>>(setComparer);
131 var queue = new HashSet<HashSet<int>>(setComparer);
145 var queue = new HashSet<HashSet<int>>(setComparer);
132
146
133 // получаем конечные состояния, сгруппированные по маркерам
147 // получаем конечные состояния, сгруппированные по маркерам
134 optimalStates.UnionWith(
148 optimalStates.UnionWith(
135 GroupFinalStates()
149 GroupFinalStates()
136 );
150 );
137
151
138 var state = new HashSet<int>(
152 var state = new HashSet<int>(
139 Enumerable
153 Enumerable
140 .Range(0, m_stateCount - 1)
154 .Range(0, m_stateCount - 1)
141 .Where(i => !m_finalStates.Contains(i))
155 .Where(i => !m_finalStates.Contains(i))
142 );
156 );
143
157
144 optimalStates.Add(state);
158 optimalStates.Add(state);
145 queue.Add(state);
159 queue.Add(state);
146
160
147 var rmap = m_transitions
161 var rmap = m_transitions
148 .GroupBy(t => t.s2)
162 .GroupBy(t => t.s2)
149 .ToLookup(
163 .ToLookup(
150 g => g.Key, // s2
164 g => g.Key, // s2
151 g => g.ToLookup(t => t.edge, t => t.s1)
165 g => g.ToLookup(t => t.edge, t => t.s1)
152 );
166 );
153
167
154 while (queue.Count > 0) {
168 while (queue.Count > 0) {
155 var stateA = queue.First();
169 var stateA = queue.First();
156 queue.Remove(stateA);
170 queue.Remove(stateA);
157
171
158 for (int c = 0; c < m_symbolCount; c++) {
172 for (int c = 0; c < m_symbolCount; c++) {
159 var stateX = new HashSet<int>();
173 var stateX = new HashSet<int>();
160 foreach(var a in stateA)
174 foreach(var a in stateA)
161 stateX.UnionWith(rmap[a][c]); // all states from wich 'c' leads to 'a'
175 stateX.UnionWith(rmap[a][c]); // all states from wich 'c' leads to 'a'
162
176
163 foreach (var stateY in optimalStates.ToArray()) {
177 foreach (var stateY in optimalStates.ToArray()) {
164 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) {
178 if (stateX.Overlaps(stateY) && !stateY.IsSubsetOf(stateX)) {
165 var stateR1 = new HashSet<int>(stateY);
179 var stateR1 = new HashSet<int>(stateY);
166 var stateR2 = new HashSet<int>(stateY);
180 var stateR2 = new HashSet<int>(stateY);
167
181
168 stateR1.IntersectWith(stateX);
182 stateR1.IntersectWith(stateX);
169 stateR2.ExceptWith(stateX);
183 stateR2.ExceptWith(stateX);
170
184
171 optimalStates.Remove(stateY);
185 optimalStates.Remove(stateY);
172 optimalStates.Add(stateR1);
186 optimalStates.Add(stateR1);
173 optimalStates.Add(stateR2);
187 optimalStates.Add(stateR2);
174
188
175 if (queue.Contains(stateY)) {
189 if (queue.Contains(stateY)) {
176 queue.Remove(stateY);
190 queue.Remove(stateY);
177 queue.Add(stateR1);
191 queue.Add(stateR1);
178 queue.Add(stateR2);
192 queue.Add(stateR2);
179 } else {
193 } else {
180 queue.Add(stateR1.Count <= stateR2.Count ? stateR1 : stateR2);
194 queue.Add(stateR1.Count <= stateR2.Count ? stateR1 : stateR2);
181 }
195 }
182 }
196 }
183 }
197 }
184 }
198 }
185 }
199 }
186
200
187 // карта получения оптимального состояния по соотвествующему ему простому состоянию
201 // карта получения оптимального состояния по соотвествующему ему простому состоянию
188 var nextState = 0;
202 var nextState = 0;
189 foreach (var item in optimalStates) {
203 foreach (var item in optimalStates) {
190 var id = nextState++;
204 var id = nextState++;
191 foreach (var s in item)
205 foreach (var s in item)
192 stateMap[s] = id;
206 stateMap[s] = id;
193 }
207 }
194
208
195 // получаем минимальный алфавит
209 // получаем минимальный алфавит
196 // входные символы не различимы, если Move(s,a1) == Move(s,a2), для любого s
210 // входные символы не различимы, если Move(s,a1) == Move(s,a2), для любого s
197 // для этого используем алгоритм кластеризации, сначала
211 // для этого используем алгоритм кластеризации, сначала
198 // считаем, что все символы не различимы
212 // считаем, что все символы не различимы
199
213
200 var minClasses = new HashSet<HashSet<int>>(setComparer);
214 var minClasses = new HashSet<HashSet<int>>(setComparer);
201 var alphaQueue = new Queue<HashSet<int>>();
215 var alphaQueue = new Queue<HashSet<int>>();
202 alphaQueue.Enqueue(new HashSet<int>(Enumerable.Range(0,AlphabetSize)));
216 alphaQueue.Enqueue(new HashSet<int>(Enumerable.Range(0,AlphabetSize)));
203
217
204 // для всех состояний, будем проверять каждый класс на различимость,
218 // для всех состояний, будем проверять каждый класс на различимость,
205 // т.е. символы различимы, если они приводят к разным состояниям
219 // т.е. символы различимы, если они приводят к разным состояниям
206 for (int s = 0 ; s < optimalStates.Count; s++) {
220 for (int s = 0 ; s < optimalStates.Count; s++) {
207 var newQueue = new Queue<HashSet<int>>();
221 var newQueue = new Queue<HashSet<int>>();
208
222
209 foreach (var A in alphaQueue) {
223 foreach (var A in alphaQueue) {
210 // классы из одного символа делить бесполезно, переводим их сразу в
224 // классы из одного символа делить бесполезно, переводим их сразу в
211 // результирующий алфавит
225 // результирующий алфавит
212 if (A.Count == 1) {
226 if (A.Count == 1) {
213 minClasses.Add(A);
227 minClasses.Add(A);
214 continue;
228 continue;
215 }
229 }
216
230
217 // различаем классы символов, которые переводят в различные оптимальные состояния
231 // различаем классы символов, которые переводят в различные оптимальные состояния
218 // optimalState -> alphaClass
232 // optimalState -> alphaClass
219 var classes = new Dictionary<int, HashSet<int>>();
233 var classes = new Dictionary<int, HashSet<int>>();
220
234
221 foreach (var term in A) {
235 foreach (var term in A) {
222 // ищем все переходы класса по символу term
236 // ищем все переходы класса по символу term
223 var res = m_transitions.Where(t => stateMap[t.s1] == s && t.edge == term).Select(t => stateMap[t.s2]).ToArray();
237 var res = m_transitions.Where(t => stateMap[t.s1] == s && t.edge == term).Select(t => stateMap[t.s2]).ToArray();
224
238
225 var s2 = res.Length > 0 ? res[0] : -1;
239 var s2 = res.Length > 0 ? res[0] : -1;
226
240
227 HashSet<int> a2;
241 HashSet<int> a2;
228 if (!classes.TryGetValue(s2, out a2)) {
242 if (!classes.TryGetValue(s2, out a2)) {
229 a2 = new HashSet<int>();
243 a2 = new HashSet<int>();
230 newQueue.Enqueue(a2);
244 newQueue.Enqueue(a2);
231 classes[s2] = a2;
245 classes[s2] = a2;
232 }
246 }
233 a2.Add(term);
247 a2.Add(term);
234 }
248 }
235 }
249 }
236
250
237 if (newQueue.Count == 0)
251 if (newQueue.Count == 0)
238 break;
252 break;
239 alphaQueue = newQueue;
253 alphaQueue = newQueue;
240 }
254 }
241
255
242 // после окончания работы алгоритма в очереди останутся минимальные различимые классы
256 // после окончания работы алгоритма в очереди останутся минимальные различимые классы
243 // входных символов
257 // входных символов
244 foreach (var A in alphaQueue)
258 foreach (var A in alphaQueue)
245 minClasses.Add(A);
259 minClasses.Add(A);
246
260
247 // построение отображения алфавитов входных символов.
261 // построение отображения алфавитов входных символов.
248 // поскольку символ DFAConst.UNCLASSIFIED_INPUT может иметь
262 // поскольку символ DFAConst.UNCLASSIFIED_INPUT может иметь
249 // специальное значение, тогда сохраним минимальный класс,
263 // специальное значение, тогда сохраним минимальный класс,
250 // содержащий этот символ на томже месте.
264 // содержащий этот символ на томже месте.
251
265
252 var nextCls = 0;
266 var nextCls = 0;
253 foreach (var item in minClasses) {
267 foreach (var item in minClasses) {
254 if (nextCls == DFAConst.UNCLASSIFIED_INPUT)
268 if (nextCls == DFAConst.UNCLASSIFIED_INPUT)
255 nextCls++;
269 nextCls++;
256
270
257 // сохраняем DFAConst.UNCLASSIFIED_INPUT
271 // сохраняем DFAConst.UNCLASSIFIED_INPUT
258 var cls = item.Contains(DFAConst.UNCLASSIFIED_INPUT) ? DFAConst.UNCLASSIFIED_INPUT : nextCls;
272 var cls = item.Contains(DFAConst.UNCLASSIFIED_INPUT) ? DFAConst.UNCLASSIFIED_INPUT : nextCls;
259
273
260 foreach (var a in item)
274 foreach (var a in item)
261 alphabetMap[a] = cls;
275 alphabetMap[a] = cls;
262
276
263 nextCls++;
277 nextCls++;
264 }
278 }
265
279
266 // построение автомата
280 // построение автомата
267 optimalDFA.SetInitialState(stateMap[m_initialState]);
281 optimalDFA.SetInitialState(stateMap[m_initialState]);
268
282
269 foreach (var sf in m_finalStates.Select(s => stateMap[s]).Distinct())
283 foreach (var sf in m_finalStates.Select(s => stateMap[s]).Distinct())
270 optimalDFA.MarkFinalState(sf);
284 optimalDFA.MarkFinalState(sf);
271
285
272 foreach (var t in m_transitions.Select(t => new AutomatonTransition(stateMap[t.s1],stateMap[t.s2],alphabetMap[t.edge])).Distinct())
286 foreach (var t in m_transitions.Select(t => new AutomatonTransition(stateMap[t.s1],stateMap[t.s2],alphabetMap[t.edge])).Distinct())
273 optimalDFA.Add(t);
287 optimalDFA.Add(t);
274 }
288 }
275
289
276 protected void PrintDFA<TInput, TState>(IAlphabet<TInput> inputAlphabet, IAlphabet<TState> stateAlphabet) {
290 protected void PrintDFA<TInput, TState>(IAlphabet<TInput> inputAlphabet, IAlphabet<TState> stateAlphabet) {
277 Safe.ArgumentNotNull(inputAlphabet, "inputAlphabet");
291 Safe.ArgumentNotNull(inputAlphabet, "inputAlphabet");
278 Safe.ArgumentNotNull(stateAlphabet, "stateAlphabet");
292 Safe.ArgumentNotNull(stateAlphabet, "stateAlphabet");
279
293
280 foreach(var t in m_transitions)
294 foreach(var t in m_transitions)
281 Console.WriteLine(
295 Console.WriteLine(
282 "[{0}] -{{{1}}}-> [{2}]{3}",
296 "[{0}] -{{{1}}}-> [{2}]{3}",
283 String.Join(",", stateAlphabet.GetSymbols(t.s1)),
297 String.Join(",", stateAlphabet.GetSymbols(t.s1)),
284 String.Join("", inputAlphabet.GetSymbols(t.edge)),
298 String.Join("", inputAlphabet.GetSymbols(t.edge)),
285 String.Join(",", stateAlphabet.GetSymbols(t.s2)),
299 String.Join(",", stateAlphabet.GetSymbols(t.s2)),
286 m_finalStates.Contains(t.s2) ? "$" : ""
300 m_finalStates.Contains(t.s2) ? "$" : ""
287 );
301 );
288 }
302 }
289
303
290 }
304 }
291 }
305 }
@@ -1,86 +1,94
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Diagnostics;
4 using System.Diagnostics;
5 using System.Linq;
5 using System.Linq;
6
6
7 namespace Implab.Automaton {
7 namespace Implab.Automaton {
8 /// <summary>
8 /// <summary>
9 /// Indexed alphabet is the finite set of symbols where each symbol has a zero-based unique index.
9 /// Indexed alphabet is the finite set of symbols where each symbol has a zero-based unique index.
10 /// </summary>
10 /// </summary>
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> : IAlphabetBuilder<T> {
17 int m_nextId = 1;
17 int m_nextId = 1;
18 readonly int[] m_map;
18 readonly int[] m_map;
19
19
20 protected IndexedAlphabetBase(int mapSize) {
20 protected IndexedAlphabetBase(int mapSize) {
21 m_map = new int[mapSize];
21 m_map = new int[mapSize];
22 }
22 }
23
23
24 protected IndexedAlphabetBase(int[] map) {
24 protected IndexedAlphabetBase(int[] map) {
25 Debug.Assert(map != null && map.Length > 0);
25 Debug.Assert(map != null && map.Length > 0);
26 Debug.Assert(map.All(x => x >= 0));
26 Debug.Assert(map.All(x => x >= 0));
27
27
28 m_map = map;
28 m_map = map;
29 m_nextId = map.Max() + 1;
29 m_nextId = map.Max() + 1;
30 }
30 }
31
31
32 public int DefineSymbol(T symbol) {
32 public int DefineSymbol(T symbol) {
33 var index = GetSymbolIndex(symbol);
33 var index = GetSymbolIndex(symbol);
34 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT)
34 if (m_map[index] == DFAConst.UNCLASSIFIED_INPUT)
35 m_map[index] = m_nextId++;
35 m_map[index] = m_nextId++;
36 return m_map[index];
36 return m_map[index];
37 }
37 }
38
38
39 public int DefineSymbol(T symbol, int cls) {
39 public int DefineSymbol(T symbol, int cls) {
40 var index = GetSymbolIndex(symbol);
40 var index = GetSymbolIndex(symbol);
41 m_map[index] = cls;
41 m_map[index] = cls;
42 m_nextId = Math.Max(cls + 1, m_nextId);
42 m_nextId = Math.Max(cls + 1, m_nextId);
43 return cls;
43 return cls;
44 }
44 }
45
45
46 public int DefineClass(IEnumerable<T> symbols) {
46 public int DefineClass(IEnumerable<T> symbols) {
47 return DefineClass(symbols, m_nextId);
47 return DefineClass(symbols, m_nextId);
48 }
48 }
49
49
50 public int DefineClass(IEnumerable<T> symbols, int cls) {
50 public int DefineClass(IEnumerable<T> symbols, int cls) {
51 Safe.ArgumentNotNull(symbols, "symbols");
51 Safe.ArgumentNotNull(symbols, "symbols");
52 symbols = symbols.Distinct();
52 symbols = symbols.Distinct();
53
53
54 foreach (var symbol in symbols)
54 foreach (var symbol in symbols)
55 m_map[GetSymbolIndex(symbol)] = cls;
55 m_map[GetSymbolIndex(symbol)] = cls;
56
56
57 m_nextId = Math.Max(cls + 1, m_nextId);
57 m_nextId = Math.Max(cls + 1, m_nextId);
58
58
59 return cls;
59 return cls;
60 }
60 }
61
61
62 public virtual int Translate(T symbol) {
62 public virtual int Translate(T symbol) {
63 return m_map[GetSymbolIndex(symbol)];
63 return m_map[GetSymbolIndex(symbol)];
64 }
64 }
65
65
66 public int Count {
66 public int Count {
67 get { return m_nextId; }
67 get { return m_nextId; }
68 }
68 }
69
69
70 public bool Contains(T symbol) {
70 public bool Contains(T symbol) {
71 return true;
71 return true;
72 }
72 }
73
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 }
79
74 public abstract int GetSymbolIndex(T symbol);
80 public abstract int GetSymbolIndex(T symbol);
75
81
82 public abstract T GetSymbolByIndex(int index);
83
76 public abstract IEnumerable<T> InputSymbols { get; }
84 public abstract IEnumerable<T> InputSymbols { get; }
77
85
78 /// <summary>
86 /// <summary>
79 /// Gets the translation map from the index of the symbol to it's class this is usefull for the optimized input symbols transtaion.
87 /// Gets the translation map from the index of the symbol to it's class this is usefull for the optimized input symbols transtaion.
80 /// </summary>
88 /// </summary>
81 /// <returns>The translation map.</returns>
89 /// <returns>The translation map.</returns>
82 public int[] GetTranslationMap() {
90 public int[] GetTranslationMap() {
83 return m_map;
91 return m_map;
84 }
92 }
85 }
93 }
86 }
94 }
@@ -1,74 +1,77
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4
4
5 namespace Implab.Automaton {
5 namespace Implab.Automaton {
6 public class MapAlphabet<T> : IAlphabetBuilder<T> {
6 public class MapAlphabet<T> : IAlphabetBuilder<T> {
7 readonly Dictionary<T,int> m_map;
7 readonly Dictionary<T,int> m_map;
8 int m_nextCls;
8 int m_nextCls;
9 readonly bool m_supportUnclassified;
9 readonly bool m_supportUnclassified;
10
10
11 public MapAlphabet(bool supportUnclassified, IEqualityComparer<T> comparer) {
11 public MapAlphabet(bool supportUnclassified, IEqualityComparer<T> comparer) {
12 m_map = comparer != null ? new Dictionary<T, int>(comparer) : new Dictionary<T,int>();
12 m_map = comparer != null ? new Dictionary<T, int>(comparer) : new Dictionary<T,int>();
13 m_supportUnclassified = supportUnclassified;
13 m_supportUnclassified = supportUnclassified;
14 m_nextCls = supportUnclassified ? 1 : 0;
14 m_nextCls = supportUnclassified ? 1 : 0;
15 }
15 }
16
16
17 #region IAlphabetBuilder implementation
17 #region IAlphabetBuilder implementation
18
18
19 public int DefineSymbol(T symbol) {
19 public int DefineSymbol(T symbol) {
20 int cls;
20 int cls;
21 return m_map.TryGetValue(symbol, out cls) ? cls : DefineSymbol(symbol, m_nextCls);
21 return m_map.TryGetValue(symbol, out cls) ? cls : DefineSymbol(symbol, m_nextCls);
22 }
22 }
23
23
24 public int DefineSymbol(T symbol, int cls) {
24 public int DefineSymbol(T symbol, int cls) {
25 Safe.ArgumentAssert(cls >= 0, "cls");
25 Safe.ArgumentAssert(cls >= 0, "cls");
26
26
27 m_nextCls = Math.Max(cls + 1, m_nextCls);
27 m_nextCls = Math.Max(cls + 1, m_nextCls);
28 m_map.Add(symbol, cls);
28 m_map.Add(symbol, cls);
29 return cls;
29 return cls;
30 }
30 }
31
31
32 public int DefineClass(IEnumerable<T> symbols) {
32 public int DefineClass(IEnumerable<T> symbols) {
33 return DefineClass(symbols, m_nextCls);
33 return DefineClass(symbols, m_nextCls);
34 }
34 }
35
35
36 public int DefineClass(IEnumerable<T> symbols, int cls) {
36 public int DefineClass(IEnumerable<T> symbols, int cls) {
37 Safe.ArgumentAssert(cls >= 0, "cls");
37 Safe.ArgumentAssert(cls >= 0, "cls");
38 Safe.ArgumentNotNull(symbols, "symbols");
38 Safe.ArgumentNotNull(symbols, "symbols");
39
39
40 m_nextCls = Math.Max(cls + 1, m_nextCls);
40 m_nextCls = Math.Max(cls + 1, m_nextCls);
41 symbols = symbols.Distinct();
42
41
43 foreach (var symbol in symbols)
42 foreach (var symbol in symbols)
44 m_map[symbol] = cls;
43 m_map[symbol] = cls;
45 return cls;
44 return cls;
46 }
45 }
47
46
48 #endregion
47 #endregion
49
48
50 #region IAlphabet implementation
49 #region IAlphabet implementation
51
50
52 public int Translate(T symbol) {
51 public int Translate(T symbol) {
53 int cls;
52 int cls;
54 if (m_map.TryGetValue(symbol, out cls))
53 if (m_map.TryGetValue(symbol, out cls))
55 return cls;
54 return cls;
56 if (!m_supportUnclassified)
55 if (!m_supportUnclassified)
57 throw new ArgumentOutOfRangeException("symbol", "The specified symbol isn't in the alphabet");
56 throw new ArgumentOutOfRangeException("symbol", "The specified symbol isn't in the alphabet");
58 return DFAConst.UNCLASSIFIED_INPUT;
57 return DFAConst.UNCLASSIFIED_INPUT;
59 }
58 }
60
59
61 public int Count {
60 public int Count {
62 get {
61 get {
63 return m_nextCls;
62 return m_nextCls;
64 }
63 }
65 }
64 }
66
65
67 public bool Contains(T symbol) {
66 public bool Contains(T symbol) {
68 return m_supportUnclassified || m_map.ContainsKey(symbol);
67 return m_supportUnclassified || m_map.ContainsKey(symbol);
69 }
68 }
70
69
70
71 public IEnumerable<T> GetSymbols(int cls) {
72 return m_map.Where(p => p.Value == cls).Select(p => p.Key);
73 }
71 #endregion
74 #endregion
72 }
75 }
73 }
76 }
74
77
@@ -1,23 +1,23
1 using System;
1 using System;
2
2
3 namespace Implab.Automaton.RegularExpressions {
3 namespace Implab.Automaton.RegularExpressions {
4 public struct DFAStateDescriptorT<T> {
4 public struct DFAStateDescriptor<T> {
5 public readonly bool final;
5 public readonly bool final;
6
6
7 public readonly int[] transitions;
7 public readonly int[] transitions;
8
8
9 public readonly T[] tags;
9 public readonly T[] tags;
10
10
11 public DFAStateDescriptorT(int size, bool final, T[] tags) {
11 public DFAStateDescriptor(int size, bool final, T[] tags) {
12 Safe.ArgumentAssert(size >= 0, "size");
12 Safe.ArgumentAssert(size >= 0, "size");
13 this.final = final;
13 this.final = final;
14 this.tags = tags;
14 this.tags = tags;
15
15
16 transitions = new int[size];
16 transitions = new int[size];
17
17
18 for (int i = 0; i < size; i++)
18 for (int i = 0; i < size; i++)
19 transitions[i] = DFAConst.UNREACHABLE_STATE;
19 transitions[i] = DFAConst.UNREACHABLE_STATE;
20 }
20 }
21 }
21 }
22 }
22 }
23
23
@@ -1,91 +1,89
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.Linq;
4 using System.Linq;
5
5
6 namespace Implab.Automaton.RegularExpressions {
6 namespace Implab.Automaton.RegularExpressions {
7 /// <summary>
7 /// <summary>
8 /// Базовый абстрактный класс. Грамматика, позволяет формулировать выражения над алфавитом типа <c>char</c>.
8 /// Базовый абстрактный класс. Грамматика, позволяет формулировать выражения над алфавитом типа <c>char</c>.
9 /// </summary>
9 /// </summary>
10 public abstract class Grammar<TSymbol, TTag> {
10 public abstract class Grammar<TSymbol, TTag> {
11
11
12 protected abstract IAlphabetBuilder<TSymbol> AlphabetBuilder {
12 protected abstract IAlphabetBuilder<TSymbol> AlphabetBuilder {
13 get;
13 get;
14 }
14 }
15
15
16 protected SymbolToken<TTag> UnclassifiedToken() {
16 protected SymbolToken<TTag> UnclassifiedToken() {
17 return new SymbolToken<TTag>(DFAConst.UNCLASSIFIED_INPUT);
17 return new SymbolToken<TTag>(DFAConst.UNCLASSIFIED_INPUT);
18 }
18 }
19
19
20 protected void DefineAlphabet(IEnumerable<TSymbol> alphabet) {
20 protected void DefineAlphabet(IEnumerable<TSymbol> alphabet) {
21 Safe.ArgumentNotNull(alphabet, "alphabet");
21 Safe.ArgumentNotNull(alphabet, "alphabet");
22
22
23 foreach (var ch in alphabet)
23 foreach (var ch in alphabet)
24 AlphabetBuilder.DefineSymbol(ch);
24 AlphabetBuilder.DefineSymbol(ch);
25 }
25 }
26
26
27 protected Token<TTag> SymbolToken(TSymbol symbol) {
27 protected Token<TTag> SymbolToken(TSymbol symbol) {
28 return Token<TTag>.New(TranslateOrAdd(symbol));
28 return Token<TTag>.New(TranslateOrAdd(symbol));
29 }
29 }
30
30
31 protected Token<TTag> SymbolToken(IEnumerable<TSymbol> symbols) {
31 protected Token<TTag> SymbolToken(IEnumerable<TSymbol> symbols) {
32 Safe.ArgumentNotNull(symbols, "symbols");
32 Safe.ArgumentNotNull(symbols, "symbols");
33
33
34 return Token<TTag>.New(TranslateOrAdd(symbols).ToArray());
34 return Token<TTag>.New(TranslateOrAdd(symbols).ToArray());
35 }
35 }
36
36
37 protected Token<TTag> SymbolSetToken(params TSymbol[] set) {
37 protected Token<TTag> SymbolSetToken(params TSymbol[] set) {
38 return SymbolToken(set);
38 return SymbolToken(set);
39 }
39 }
40
40
41 int TranslateOrAdd(TSymbol ch) {
41 int TranslateOrAdd(TSymbol ch) {
42 var t = AlphabetBuilder.Translate(ch);
42 var t = AlphabetBuilder.Translate(ch);
43 if (t == DFAConst.UNCLASSIFIED_INPUT)
43 if (t == DFAConst.UNCLASSIFIED_INPUT)
44 t = AlphabetBuilder.DefineSymbol(ch);
44 t = AlphabetBuilder.DefineSymbol(ch);
45 return t;
45 return t;
46 }
46 }
47
47
48 IEnumerable<int> TranslateOrAdd(IEnumerable<TSymbol> symbols) {
48 IEnumerable<int> TranslateOrAdd(IEnumerable<TSymbol> symbols) {
49 return symbols.Distinct().Select(TranslateOrAdd);
49 return symbols.Distinct().Select(TranslateOrAdd);
50 }
50 }
51
51
52 int TranslateOrDie(TSymbol ch) {
52 int TranslateOrDie(TSymbol ch) {
53 var t = AlphabetBuilder.Translate(ch);
53 var t = AlphabetBuilder.Translate(ch);
54 if (t == DFAConst.UNCLASSIFIED_INPUT)
54 if (t == DFAConst.UNCLASSIFIED_INPUT)
55 throw new ApplicationException(String.Format("Symbol '{0}' is UNCLASSIFIED", ch));
55 throw new ApplicationException(String.Format("Symbol '{0}' is UNCLASSIFIED", ch));
56 return t;
56 return t;
57 }
57 }
58
58
59 IEnumerable<int> TranslateOrDie(IEnumerable<TSymbol> symbols) {
59 IEnumerable<int> TranslateOrDie(IEnumerable<TSymbol> symbols) {
60 return symbols.Distinct().Select(TranslateOrDie);
60 return symbols.Distinct().Select(TranslateOrDie);
61 }
61 }
62
62
63 protected Token<TTag> SymbolTokenExcept(IEnumerable<TSymbol> symbols) {
63 protected Token<TTag> SymbolTokenExcept(IEnumerable<TSymbol> symbols) {
64 Safe.ArgumentNotNull(symbols, "symbols");
64 Safe.ArgumentNotNull(symbols, "symbols");
65
65
66 return Token<TTag>.New( Enumerable.Range(0, AlphabetBuilder.Count).Except(TranslateOrDie(symbols)).ToArray() );
66 return Token<TTag>.New( Enumerable.Range(0, AlphabetBuilder.Count).Except(TranslateOrDie(symbols)).ToArray() );
67 }
67 }
68
68
69 protected void BuildDFA(Token<TTag> lang, IDFATableBuilder<TTag> dfaTable, IAlphabetBuilder<TSymbol> dfaAlphabet) {
69 protected abstract IAlphabetBuilder<TSymbol> CreateAlphabet();
70 Safe.ArgumentNotNull(lang, "lang");
71 Safe.ArgumentNotNull(dfaAlphabet, "dfaAlphabet");
72
73 var dfa = new RegularDFADefinition<TSymbol, TTag>(AlphabetBuilder);
74
70
75 var builder = new RegularDFABuilder<TTag>();
71 protected RegularDFA<TSymbol, TTag> BuildDFA(Token<TTag> regexp) {
72
73 var dfa = new RegularDFA<TSymbol, TTag>(AlphabetBuilder);
76
74
77 lang.Accept( builder );
75 var visitor = new RegularExpressionVisitor<TTag>();
76 regexp.Accept( visitor );
78
77
79 builder.BuildDFA(dfa);
78 visitor.BuildDFA(dfa);
80
79
81 if (dfa.IsFinalState(dfa.InitialState))
80 if (dfa.IsFinalState(dfa.InitialState))
82 throw new ApplicationException("The specified language contains empty token");
81 throw new ApplicationException("The specified language contains empty token");
83
82
84 dfa.Optimize(dfaTable, dfaAlphabet);
83 return dfa.Optimize(CreateAlphabet());
85
86 }
84 }
87
85
88 }
86 }
89
87
90
88
91 }
89 }
@@ -1,265 +1,255
1 using Implab;
1 using Implab;
2 using System;
2 using System;
3 using System.Collections.Generic;
3 using System.Collections.Generic;
4 using System.IO;
4 using System.IO;
5 using Implab.Components;
5 using Implab.Components;
6 using Implab.Automaton.RegularExpressions;
6
7
7 namespace Implab.Automaton {
8 namespace Implab.Automaton {
8 /// <summary>
9 /// <summary>
9 /// Базовый класс для разбора потока входных символов на токены.
10 /// Базовый класс для разбора потока входных символов на токены.
10 /// </summary>
11 /// </summary>
11 /// <remarks>
12 /// <remarks>
12 /// Сканнер имеет внутри буффер с симолами входного текста, по которому перемещаются два
13 /// Сканнер имеет внутри буффер с симолами входного текста, по которому перемещаются два
13 /// указателя, начала и конца токена, при перемещении искользуется ДКА для определения
14 /// указателя, начала и конца токена, при перемещении искользуется ДКА для определения
14 /// конца токена и допустимости текущего символа.
15 /// конца токена и допустимости текущего символа.
15 /// </remarks>
16 /// </remarks>
16 public abstract class Scanner<TTag> : Disposable {
17 public abstract class Scanner<TTag> : Disposable {
17 struct ScannerConfig {
18 protected struct ScannerConfig {
18 public DFAStateDescriptior<TTag>[] states;
19 public readonly DFAStateDescriptor<TTag>[] states;
19 public int[] alphabetMap;
20 public readonly int[] alphabet;
20 public int initialState;
21 public readonly int initialState;
22
23 public ScannerConfig(DFAStateDescriptor<TTag>[] states, int[] alphabet, int initialState) {
24 this.initialState = initialState;
25 this.alphabet = alphabet;
26 this.states = states;
27 }
21 }
28 }
22
29
23 Stack<ScannerConfig> m_defs = new Stack<ScannerConfig>();
30 Stack<ScannerConfig> m_defs = new Stack<ScannerConfig>();
24
31
25 DFAStateDescriptior<TTag>[] m_states;
32 ScannerConfig m_config;
26 int[] m_alphabetMap;
27 int m_initialState;
28
33
29 protected DFAStateDescriptior<TTag> m_currentState;
34 protected DFAStateDescriptor<TTag> m_currentState;
30 int m_previewCode;
35 int m_previewCode;
31
36
32 protected int m_tokenLen;
37 protected int m_tokenLen;
33 protected int m_tokenOffset;
38 protected int m_tokenOffset;
34
39
35 protected char[] m_buffer;
40 protected char[] m_buffer;
36 protected int m_bufferSize;
41 protected int m_bufferSize;
37 protected int m_pointer;
42 protected int m_pointer;
38
43
39 TextReader m_reader;
44 TextReader m_reader;
40 bool m_disposeReader;
45 bool m_disposeReader;
41 int m_chunkSize = 1024; // 1k
46 int m_chunkSize = 1024; // 1k
42 int m_limit = 10 * 1024 * 1024; // 10Mb
47 int m_limit = 10 * 1024 * 1024; // 10Mb
43
48
44 protected Scanner(DFAStateDescriptior<TTag>[] states, int[] alphabet, int initialState) {
49 protected Scanner(ScannerConfig config) {
45 Safe.ArgumentNotEmpty(states, "states");
50 Safe.ArgumentNotEmpty(config.states, "config.states");
46 Safe.ArgumentNotNull(alphabet, "alphabet");
51 Safe.ArgumentNotNull(config.alphabet, "config.alphabet");
47
52
48 m_states = states;
53 m_config = config;
49 m_alphabetMap = alphabet;
50 m_initialState = initialState;
51
52 Feed(new char[0]);
53 }
54 }
54
55
55 /// <summary>
56 /// <summary>
56 /// Заполняет входными данными буффер.
57 /// Заполняет входными данными буффер.
57 /// </summary>
58 /// </summary>
58 /// <param name="data">Данные для обработки.</param>
59 /// <param name="data">Данные для обработки.</param>
59 /// <remarks>Копирование данных не происходит, переданный массив используется в
60 /// <remarks>Копирование данных не происходит, переданный массив используется в
60 /// качестве входного буффера.</remarks>
61 /// качестве входного буффера.</remarks>
61 public void Feed(char[] data) {
62 public void Feed(char[] data) {
62 Safe.ArgumentNotNull(data, "data");
63 Safe.ArgumentNotNull(data, "data");
63
64
64 Feed(data, data.Length);
65 Feed(data, data.Length);
65 }
66 }
66
67
67 /// <summary>
68 /// <summary>
68 /// Заполняет буффур чтения входными данными.
69 /// Заполняет буффур чтения входными данными.
69 /// </summary>
70 /// </summary>
70 /// <param name="data">Данные для обработки.</param>
71 /// <param name="data">Данные для обработки.</param>
71 /// <param name="length">Длина данных для обработки.</param>
72 /// <param name="length">Длина данных для обработки.</param>
72 /// <remarks>Копирование данных не происходит, переданный массив используется в
73 /// <remarks>Копирование данных не происходит, переданный массив используется в
73 /// качестве входного буффера.</remarks>
74 /// качестве входного буффера.</remarks>
74 public void Feed(char[] data, int length) {
75 public void Feed(char[] data, int length) {
75 Safe.ArgumentNotNull(data, "data");
76 Safe.ArgumentNotNull(data, "data");
76 Safe.ArgumentInRange(length, 0, data.Length, "length");
77 Safe.ArgumentInRange(length, 0, data.Length, "length");
77 AssertNotDisposed();
78 AssertNotDisposed();
78
79
79 m_pointer = -1;
80 m_pointer = -1;
80 m_buffer = data;
81 m_buffer = data;
81 m_bufferSize = length;
82 m_bufferSize = length;
82 Shift();
83 Shift();
83 }
84 }
84
85
85 public void Feed(TextReader reader, bool dispose) {
86 public void Feed(TextReader reader, bool dispose) {
86 Safe.ArgumentNotNull(reader, "reader");
87 Safe.ArgumentNotNull(reader, "reader");
87 AssertNotDisposed();
88 AssertNotDisposed();
88
89
89 if (m_reader != null && m_disposeReader)
90 if (m_reader != null && m_disposeReader)
90 m_reader.Dispose();
91 m_reader.Dispose();
91
92
92 m_reader = reader;
93 m_reader = reader;
93 m_disposeReader = dispose;
94 m_disposeReader = dispose;
94 m_pointer = -1;
95 m_pointer = -1;
95 m_buffer = new char[m_chunkSize];
96 m_buffer = new char[m_chunkSize];
96 m_bufferSize = 0;
97 m_bufferSize = 0;
97 Shift();
98 Shift();
98 }
99 }
99
100
100 /// <summary>
101 /// <summary>
101 /// Получает текущий токен в виде строки.
102 /// Получает текущий токен в виде строки.
102 /// </summary>
103 /// </summary>
103 /// <returns></returns>
104 /// <returns></returns>
104 protected string GetTokenValue() {
105 protected string GetTokenValue() {
105 return new String(m_buffer, m_tokenOffset, m_tokenLen);
106 return new String(m_buffer, m_tokenOffset, m_tokenLen);
106 }
107 }
107
108
108 /// <summary>
109 /// <summary>
109 /// Метки текущего токена, которые были назначены в регулярном выражении.
110 /// Метки текущего токена, которые были назначены в регулярном выражении.
110 /// </summary>
111 /// </summary>
111 protected TTag[] TokenTags {
112 protected TTag[] TokenTags {
112 get {
113 get {
113 return m_currentState.tag;
114 return m_currentState.tags;
114 }
115 }
115 }
116 }
116
117
117 /// <summary>
118 /// <summary>
118 /// Признак конца данных
119 /// Признак конца данных
119 /// </summary>
120 /// </summary>
120 public bool EOF {
121 public bool EOF {
121 get {
122 get {
122 return m_pointer >= m_bufferSize;
123 return m_pointer >= m_bufferSize;
123 }
124 }
124 }
125 }
125
126
126 /// <summary>
127 /// <summary>
127 /// Читает следующий токен, при этом <see cref="m_tokenOffset"/> указывает на начало токена,
128 /// Читает следующий токен, при этом <see cref="m_tokenOffset"/> указывает на начало токена,
128 /// <see cref="m_tokenLen"/> на длину токена, <see cref="m_buffer"/> - массив символов, в
129 /// <see cref="m_tokenLen"/> на длину токена, <see cref="m_buffer"/> - массив символов, в
129 /// котором находится токен.
130 /// котором находится токен.
130 /// </summary>
131 /// </summary>
131 /// <returns><c>false</c> - достигнут конец данных, токен не прочитан.</returns>
132 /// <returns><c>false</c> - достигнут конец данных, токен не прочитан.</returns>
132 protected bool ReadTokenInternal() {
133 protected bool ReadTokenInternal() {
133 if (m_pointer >= m_bufferSize)
134 if (m_pointer >= m_bufferSize)
134 return false;
135 return false;
135
136
136 m_currentState = m_states[m_initialState];
137 m_currentState = m_config.states[m_config.initialState];
137 m_tokenLen = 0;
138 m_tokenLen = 0;
138 m_tokenOffset = m_pointer;
139 m_tokenOffset = m_pointer;
139 int nextState;
140 int nextState;
140 do {
141 do {
141 nextState = m_currentState.transitions[m_previewCode];
142 nextState = m_currentState.transitions[m_previewCode];
142 if (nextState == DFAConst.UNREACHABLE_STATE) {
143 if (nextState == DFAConst.UNREACHABLE_STATE) {
143 if (m_currentState.final)
144 if (m_currentState.final)
144 return true;
145 return true;
145
146
146 throw new ParserException(
147 throw new ParserException(
147 String.Format(
148 String.Format(
148 "Unexpected symbol '{0}', at pos {1}",
149 "Unexpected symbol '{0}', at pos {1}",
149 m_buffer[m_pointer],
150 m_buffer[m_pointer],
150 Position
151 Position
151 )
152 )
152 );
153 );
153 }
154 }
154 m_currentState = m_states[nextState];
155 m_currentState = m_config.states[nextState];
155 m_tokenLen++;
156 m_tokenLen++;
156
157
157 } while (Shift());
158 } while (Shift());
158
159
159 // END OF DATA
160 // END OF DATA
160 if (!m_currentState.final)
161 if (!m_currentState.final)
161 throw new ParserException("Unexpected end of data");
162 throw new ParserException("Unexpected end of data");
162
163
163 return true;
164 return true;
164 }
165 }
165
166
166
167
167 bool Shift() {
168 bool Shift() {
168 m_pointer++;
169 m_pointer++;
169
170
170 if (m_pointer >= m_bufferSize) {
171 if (m_pointer >= m_bufferSize) {
171 if (!ReadNextChunk())
172 if (!ReadNextChunk())
172 return false;
173 return false;
173 }
174 }
174
175
175 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
176 m_previewCode = m_config.alphabet[m_buffer[m_pointer]];
176
177
177 return true;
178 return true;
178 }
179 }
179
180
180 bool ReadNextChunk() {
181 bool ReadNextChunk() {
181 if (m_reader == null)
182 if (m_reader == null)
182 return false;
183 return false;
183
184
184 // extend buffer if nesessary
185 // extend buffer if nesessary
185 if (m_pointer + m_chunkSize > m_buffer.Length) {
186 if (m_pointer + m_chunkSize > m_buffer.Length) {
186 // trim unused buffer head
187 // trim unused buffer head
187 var size = m_tokenLen + m_chunkSize;
188 var size = m_tokenLen + m_chunkSize;
188 if (size >= m_limit)
189 if (size >= m_limit)
189 throw new ParserException(String.Format("Input buffer {0} bytes limit exceeded", m_limit));
190 throw new ParserException(String.Format("Input buffer {0} bytes limit exceeded", m_limit));
190 var temp = new char[size];
191 var temp = new char[size];
191 Array.Copy(m_buffer, m_tokenOffset, temp, 0, m_tokenLen);
192 Array.Copy(m_buffer, m_tokenOffset, temp, 0, m_tokenLen);
192 m_pointer -= m_tokenOffset;
193 m_pointer -= m_tokenOffset;
193 m_bufferSize -= m_tokenOffset;
194 m_bufferSize -= m_tokenOffset;
194 m_tokenOffset = 0;
195 m_tokenOffset = 0;
195 m_buffer = temp;
196 m_buffer = temp;
196 }
197 }
197
198
198 var read = m_reader.Read(m_buffer, m_tokenLen, m_chunkSize);
199 var read = m_reader.Read(m_buffer, m_tokenLen, m_chunkSize);
199 if (read == 0)
200 if (read == 0)
200 return false;
201 return false;
201
202
202 m_bufferSize += read;
203 m_bufferSize += read;
203
204
204 return true;
205 return true;
205 }
206 }
206
207
207 /// <summary>
208 /// <summary>
208 /// Позиция сканнера во входном буфере
209 /// Позиция сканнера во входном буфере
209 /// </summary>
210 /// </summary>
210 public int Position {
211 public int Position {
211 get {
212 get {
212 return m_pointer + 1;
213 return m_pointer + 1;
213 }
214 }
214 }
215 }
215
216
216 /// <summary>
217 /// <summary>
217 /// Преключает внутренний ДКА на указанный, позволяет реализовать подобие захватывающей
218 /// Преключает внутренний ДКА на указанный, позволяет реализовать подобие захватывающей
218 /// группировки.
219 /// группировки.
219 /// </summary>
220 /// </summary>
220 /// <param name="states">Таблица состояний нового ДКА</param>
221 /// <param name = "config"></param>
221 /// <param name="alphabet">Таблица входных символов для нового ДКА</param>
222 protected void Switch(ScannerConfig config) {
222 /// <param name = "initialState"></param>
223 Safe.ArgumentNotNull(config.states, "config.states");
223 protected void Switch(DFAStateDescriptior<TTag>[] states, int[] alphabet, int initialState) {
224 Safe.ArgumentNotNull(states, "dfa");
225
224
226 m_defs.Push(new ScannerConfig {
225 m_defs.Push(m_config);
227 states = m_states,
226 m_config = config;
228 alphabetMap = m_alphabetMap,
229 initialState = m_initialState
230 });
231
227
232 m_states = states;
228 m_previewCode = m_config.alphabet[m_buffer[m_pointer]];
233 m_alphabetMap = alphabet;
234 m_initialState = initialState;
235
236 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
237 }
229 }
238
230
239 /// <summary>
231 /// <summary>
240 /// Восстанавливает предыдущей ДКА сканнера.
232 /// Восстанавливает предыдущей ДКА сканнера.
241 /// </summary>
233 /// </summary>
242 protected void Restore() {
234 protected void Restore() {
243 if (m_defs.Count == 0)
235 if (m_defs.Count == 0)
244 throw new InvalidOperationException();
236 throw new InvalidOperationException();
245 var prev = m_defs.Pop();
237 m_config = m_defs.Pop();
246 m_states = prev.states;
238
247 m_alphabetMap = prev.alphabetMap;
239 m_previewCode = m_config.alphabet[m_buffer[m_pointer]];
248 m_initialState = prev.initialState;
249 m_previewCode = m_alphabetMap[m_buffer[m_pointer]];
250 }
240 }
251
241
252 protected override void Dispose(bool disposing) {
242 protected override void Dispose(bool disposing) {
253 if (disposing) {
243 if (disposing) {
254 if (m_reader != null && m_disposeReader)
244 if (m_reader != null && m_disposeReader)
255 m_reader.Dispose();
245 m_reader.Dispose();
256 m_buffer = null;
246 m_buffer = null;
257 m_bufferSize = 0;
247 m_bufferSize = 0;
258 m_pointer = 0;
248 m_pointer = 0;
259 m_tokenLen = 0;
249 m_tokenLen = 0;
260 m_tokenOffset = 0;
250 m_tokenOffset = 0;
261 }
251 }
262 base.Dispose(disposing);
252 base.Dispose(disposing);
263 }
253 }
264 }
254 }
265 }
255 }
@@ -1,25 +1,29
1 using System.Collections.Generic;
1 using System.Collections.Generic;
2 using System.Linq;
2 using System.Linq;
3 using Implab.Automaton;
3 using Implab.Automaton;
4
4
5 namespace Implab.Formats {
5 namespace Implab.Formats {
6 public class ByteAlphabet : IndexedAlphabetBase<byte> {
6 public class ByteAlphabet : IndexedAlphabetBase<byte> {
7 public ByteAlphabet() : base(byte.MaxValue + 1){
7 public ByteAlphabet() : base(byte.MaxValue + 1){
8 }
8 }
9
9
10 #region implemented abstract members of IndexedAlphabetBase
10 #region implemented abstract members of IndexedAlphabetBase
11
11
12 public override int GetSymbolIndex(byte symbol) {
12 public override int GetSymbolIndex(byte symbol) {
13 return (int)symbol;
13 return (int)symbol;
14 }
14 }
15
15
16 public override byte GetSymbolByIndex(int index) {
17 return (byte)index;
18 }
19
16 public IEnumerable<byte> InputSymbols {
20 public IEnumerable<byte> InputSymbols {
17 get {
21 get {
18 return Enumerable.Range(byte.MinValue, byte.MaxValue).Cast<byte>();
22 return Enumerable.Range(byte.MinValue, byte.MaxValue).Cast<byte>();
19 }
23 }
20 }
24 }
21
25
22 #endregion
26 #endregion
23 }
27 }
24 }
28 }
25
29
@@ -1,20 +1,24
1 using System.Collections.Generic;
1 using System.Collections.Generic;
2 using System.Linq;
2 using System.Linq;
3 using Implab.Automaton;
3 using Implab.Automaton;
4
4
5 namespace Implab.Formats {
5 namespace Implab.Formats {
6 public class CharAlphabet: IndexedAlphabetBase<char> {
6 public class CharAlphabet: IndexedAlphabetBase<char> {
7
7
8 public CharAlphabet()
8 public CharAlphabet()
9 : base(char.MaxValue + 1) {
9 : base(char.MaxValue + 1) {
10 }
10 }
11
11
12 public override int GetSymbolIndex(char symbol) {
12 public override int GetSymbolIndex(char symbol) {
13 return symbol;
13 return symbol;
14 }
14 }
15
15
16 public override char GetSymbolByIndex(int index) {
17 return (char)index;
18 }
19
16 public override IEnumerable<char> InputSymbols {
20 public override IEnumerable<char> InputSymbols {
17 get { return Enumerable.Range(char.MinValue, char.MaxValue).Cast<char>(); }
21 get { return Enumerable.Range(char.MinValue, char.MaxValue).Cast<char>(); }
18 }
22 }
19 }
23 }
20 }
24 }
@@ -1,115 +1,116
1 using System.Linq;
1 using System.Linq;
2 using Implab.Automaton.RegularExpressions;
2 using Implab.Automaton.RegularExpressions;
3 using System;
3 using System;
4 using Implab.Automaton;
4
5
5 namespace Implab.Formats.JSON {
6 namespace Implab.Formats.JSON {
6 class JSONGrammar : Grammar<char,JSONGrammar.TokenType> {
7 class JSONGrammar : Grammar<char,JSONGrammar.TokenType> {
7 public enum TokenType {
8 public enum TokenType {
8 None,
9 None,
9 BeginObject,
10 BeginObject,
10 EndObject,
11 EndObject,
11 BeginArray,
12 BeginArray,
12 EndArray,
13 EndArray,
13 String,
14 String,
14 Number,
15 Number,
15 Literal,
16 Literal,
16 NameSeparator,
17 NameSeparator,
17 ValueSeparator,
18 ValueSeparator,
18
19
19 StringBound,
20 StringBound,
20 EscapedChar,
21 EscapedChar,
21 UnescapedChar,
22 UnescapedChar,
22 EscapedUnicode,
23 EscapedUnicode,
23
24
24 Minus,
25 Minus,
25 Plus,
26 Plus,
26 Sign,
27 Sign,
27 Integer,
28 Integer,
28 Dot,
29 Dot,
29 Exp
30 Exp
30 }
31 }
31
32
32 static Lazy<JSONGrammar> _instance = new Lazy<JSONGrammar>();
33 static Lazy<JSONGrammar> _instance = new Lazy<JSONGrammar>();
33
34
34 public static JSONGrammar Instance {
35 public static JSONGrammar Instance {
35 get { return _instance.Value; }
36 get { return _instance.Value; }
36 }
37 }
37
38
38 readonly RegularCharDFADefinition<TokenType> m_jsonDFA;
39 readonly RegularDFA<char, TokenType> m_jsonDFA;
39 readonly RegularCharDFADefinition<TokenType> m_stringDFA;
40 readonly RegularDFA<char, TokenType> m_stringDFA;
40
41
41 public JSONGrammar() {
42 public JSONGrammar() {
42 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
43 DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
43 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
44 var hexDigit = SymbolRangeToken('a','f').Or(SymbolRangeToken('A','F')).Or(SymbolRangeToken('0','9'));
44 var digit9 = SymbolRangeToken('1', '9');
45 var digit9 = SymbolRangeToken('1', '9');
45 var zero = SymbolToken('0');
46 var zero = SymbolToken('0');
46 var digit = zero.Or(digit9);
47 var digit = zero.Or(digit9);
47 var dot = SymbolToken('.');
48 var dot = SymbolToken('.');
48 var minus = SymbolToken('-');
49 var minus = SymbolToken('-');
49 var sign = SymbolSetToken('-', '+');
50 var sign = SymbolSetToken('-', '+');
50 var expSign = SymbolSetToken('e', 'E');
51 var expSign = SymbolSetToken('e', 'E');
51 var letters = SymbolRangeToken('a', 'z');
52 var letters = SymbolRangeToken('a', 'z');
52 var integer = zero.Or(digit9.Cat(digit.EClosure()));
53 var integer = zero.Or(digit9.Cat(digit.EClosure()));
53 var frac = dot.Cat(digit.Closure());
54 var frac = dot.Cat(digit.Closure());
54 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
55 var exp = expSign.Cat(sign.Optional()).Cat(digit.Closure());
55 var quote = SymbolToken('"');
56 var quote = SymbolToken('"');
56 var backSlash = SymbolToken('\\');
57 var backSlash = SymbolToken('\\');
57 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
58 var specialEscapeChars = SymbolSetToken('\\', '"', '/', 'b', 'f', 't', 'n', 'r');
58 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
59 var unicodeEspace = SymbolToken('u').Cat(hexDigit.Repeat(4));
59 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
60 var whitespace = SymbolSetToken('\n', '\r', '\t', ' ').EClosure();
60 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
61 var beginObject = whitespace.Cat(SymbolToken('{')).Cat(whitespace);
61 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
62 var endObject = whitespace.Cat(SymbolToken('}')).Cat(whitespace);
62 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
63 var beginArray = whitespace.Cat(SymbolToken('[')).Cat(whitespace);
63 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
64 var endArray = whitespace.Cat(SymbolToken(']')).Cat(whitespace);
64 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
65 var nameSep = whitespace.Cat(SymbolToken(':')).Cat(whitespace);
65 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
66 var valueSep = whitespace.Cat(SymbolToken(',')).Cat(whitespace);
66
67
67 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
68 var number = minus.Optional().Cat(integer).Cat(frac.Optional()).Cat(exp.Optional());
68 var literal = letters.Closure();
69 var literal = letters.Closure();
69 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
70 var unescaped = SymbolTokenExcept(Enumerable.Range(0, 0x20).Union(new int[] { '\\', '"' }).Select(x => (char)x));
70
71
71 var jsonExpression =
72 var jsonExpression =
72 number.Tag(TokenType.Number)
73 number.Tag(TokenType.Number)
73 .Or(literal.Tag(TokenType.Literal))
74 .Or(literal.Tag(TokenType.Literal))
74 .Or(quote.Tag(TokenType.StringBound))
75 .Or(quote.Tag(TokenType.StringBound))
75 .Or(beginObject.Tag(TokenType.BeginObject))
76 .Or(beginObject.Tag(TokenType.BeginObject))
76 .Or(endObject.Tag(TokenType.EndObject))
77 .Or(endObject.Tag(TokenType.EndObject))
77 .Or(beginArray.Tag(TokenType.BeginArray))
78 .Or(beginArray.Tag(TokenType.BeginArray))
78 .Or(endArray.Tag(TokenType.EndArray))
79 .Or(endArray.Tag(TokenType.EndArray))
79 .Or(nameSep.Tag(TokenType.NameSeparator))
80 .Or(nameSep.Tag(TokenType.NameSeparator))
80 .Or(valueSep.Tag(TokenType.ValueSeparator));
81 .Or(valueSep.Tag(TokenType.ValueSeparator));
81
82
82
83
83 var jsonStringExpression =
84 var jsonStringExpression =
84 quote.Tag(TokenType.StringBound)
85 quote.Tag(TokenType.StringBound)
85 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
86 .Or(backSlash.Cat(specialEscapeChars).Tag(TokenType.EscapedChar))
86 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
87 .Or(backSlash.Cat(unicodeEspace).Tag(TokenType.EscapedUnicode))
87 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
88 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
88
89
89
90
90 m_jsonDFA = new RegularCharDFADefinition<TokenType>(new CharAlphabet());
91 m_jsonDFA = BuildDFA(jsonExpression);
91 BuildDFA(jsonExpression, m_jsonDFA, m_jsonDFA.InputAlphabet);
92 m_stringDFA = BuildDFA(jsonStringExpression);
92
93
94 m_stringDFA = new RegularCharDFADefinition<TokenType>(new CharAlphabet());
95 BuildDFA(jsonStringExpression, m_jsonDFA, m_jsonDFA.InputAlphabet);
96 }
93 }
97
94
98 public RegularCharDFADefinition<TokenType> JsonDFA {
95 public RegularDFA<char, TokenType> JsonDFA {
99 get {
96 get {
100 return m_jsonDFA;
97 return m_jsonDFA;
101 }
98 }
102 }
99 }
103
100
104 public RegularDFADefinition<char,TokenType> JsonStringDFA {
101 public RegularDFA<char,TokenType> JsonStringDFA {
105 get {
102 get {
106 return m_stringDFA;
103 return m_stringDFA;
107 }
104 }
108 }
105 }
109
106
110 Token<TokenType> SymbolRangeToken(char start, char stop) {
107 Token<TokenType> SymbolRangeToken(char start, char stop) {
111 return SymbolToken(Enumerable.Range(start,stop - start).Cast<char>());
108 return SymbolToken(Enumerable.Range(start,stop - start).Cast<char>());
112 }
109 }
110
111 protected override IAlphabetBuilder<char> CreateAlphabet() {
112 return new CharAlphabet();
113 }
113
114
114 }
115 }
115 }
116 }
@@ -1,280 +1,280
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Diagnostics;
3 using System.IO;
3 using System.IO;
4 using Implab.Automaton;
4 using Implab.Automaton;
5 using Implab.Automaton.RegularExpressions;
5 using Implab.Automaton.RegularExpressions;
6 using System.Linq;
6 using System.Linq;
7 using Implab.Components;
7 using Implab.Components;
8
8
9 namespace Implab.Formats.JSON {
9 namespace Implab.Formats.JSON {
10 /// <summary>
10 /// <summary>
11 /// internal
11 /// internal
12 /// </summary>
12 /// </summary>
13 public struct JSONParserContext {
13 public struct JSONParserContext {
14 public string memberName;
14 public string memberName;
15 public JSONElementContext elementContext;
15 public JSONElementContext elementContext;
16 }
16 }
17
17
18 /// <summary>
18 /// <summary>
19 /// Pull парсер JSON данных.
19 /// Pull парсер JSON данных.
20 /// </summary>
20 /// </summary>
21 /// <remarks>
21 /// <remarks>
22 /// Следует отметить отдельную интерпретацию свойства <see cref="Level"/>,
22 /// Следует отметить отдельную интерпретацию свойства <see cref="Level"/>,
23 /// оно означает текущий уровень вложенности объектов, однако закрывающий
23 /// оно означает текущий уровень вложенности объектов, однако закрывающий
24 /// элемент объекта и массива имеет уровень меньше, чем сам объект.
24 /// элемент объекта и массива имеет уровень меньше, чем сам объект.
25 /// <code>
25 /// <code>
26 /// { // Level = 1
26 /// { // Level = 1
27 /// "name" : "Peter", // Level = 1
27 /// "name" : "Peter", // Level = 1
28 /// "address" : { // Level = 2
28 /// "address" : { // Level = 2
29 /// city : "Stern" // Level = 2
29 /// city : "Stern" // Level = 2
30 /// } // Level = 1
30 /// } // Level = 1
31 /// } // Level = 0
31 /// } // Level = 0
32 /// </code>
32 /// </code>
33 /// </remarks>
33 /// </remarks>
34 public class JSONParser : Disposable {
34 public class JSONParser : Disposable {
35
35
36 enum MemberContext {
36 enum MemberContext {
37 MemberName,
37 MemberName,
38 MemberValue
38 MemberValue
39 }
39 }
40
40
41 struct ParserContext {
41 struct ParserContext {
42 DFAStateDescriptior<object>
42 DFAStateDescriptior<object>
43 }
43 }
44
44
45 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
45 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
46 static readonly DFAStateDescriptior<object>[] _jsonDFA;
46 static readonly DFAStateDescriptior<object>[] _jsonDFA;
47 static readonly int _jsonDFAInitialState;
47 static readonly int _jsonDFAInitialState;
48 static readonly DFAStateDescriptior<object>[] _objectDFA;
48 static readonly DFAStateDescriptior<object>[] _objectDFA;
49 static readonly int _objectDFAInitialState;
49 static readonly int _objectDFAInitialState;
50 static readonly DFAStateDescriptior<object>[] _arrayDFA;
50 static readonly DFAStateDescriptior<object>[] _arrayDFA;
51 static readonly int _arrayDFAInitialState;
51 static readonly int _arrayDFAInitialState;
52
52
53 static JSONParser() {
53 static JSONParser() {
54
54
55
55
56 var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
56 var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
57 var memberExpression = Token(JsonTokenType.String).Cat(Token(JsonTokenType.NameSeparator)).Cat(valueExpression);
57 var memberExpression = Token(JsonTokenType.String).Cat(Token(JsonTokenType.NameSeparator)).Cat(valueExpression);
58
58
59 var objectExpression = memberExpression
59 var objectExpression = memberExpression
60 .Cat(
60 .Cat(
61 Token(JsonTokenType.ValueSeparator)
61 Token(JsonTokenType.ValueSeparator)
62 .Cat(memberExpression)
62 .Cat(memberExpression)
63 .EClosure()
63 .EClosure()
64 )
64 )
65 .Optional()
65 .Optional()
66 .Cat(Token(JsonTokenType.EndObject))
66 .Cat(Token(JsonTokenType.EndObject))
67 .Tag(null);
67 .Tag(null);
68 var arrayExpression = valueExpression
68 var arrayExpression = valueExpression
69 .Cat(
69 .Cat(
70 Token(JsonTokenType.ValueSeparator)
70 Token(JsonTokenType.ValueSeparator)
71 .Cat(valueExpression)
71 .Cat(valueExpression)
72 .EClosure()
72 .EClosure()
73 )
73 )
74 .Optional()
74 .Optional()
75 .Cat(Token(JsonTokenType.EndArray))
75 .Cat(Token(JsonTokenType.EndArray))
76 .Tag(null);
76 .Tag(null);
77
77
78 var jsonExpression = valueExpression.Tag(null);
78 var jsonExpression = valueExpression.Tag(null);
79
79
80 _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable();
80 _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable();
81 _objectDFA = CreateDFA(objectExpression).GetTransitionTable();
81 _objectDFA = CreateDFA(objectExpression).GetTransitionTable();
82 _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable();
82 _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable();
83 }
83 }
84
84
85 static Token<object> Token(params JsonTokenType[] input) {
85 static Token<object> Token(params JsonTokenType[] input) {
86 return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray());
86 return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray());
87 }
87 }
88
88
89 static RegularDFADefinition<JsonTokenType,object> CreateDFA(Token<object> expr) {
89 static RegularDFA<JsonTokenType,object> CreateDFA(Token<object> expr) {
90 var builder = new RegularDFABuilder<object>();
90 var builder = new RegularExpressionVisitor<object>();
91 var dfa = new RegularDFADefinition<JsonTokenType,object>(_alphabet);
91 var dfa = new RegularDFA<JsonTokenType,object>(_alphabet);
92
92
93 expr.Accept(builder);
93 expr.Accept(builder);
94
94
95 builder.BuildDFA(dfa);
95 builder.BuildDFA(dfa);
96 return dfa;
96 return dfa;
97 }
97 }
98
98
99 JSONScanner m_scanner;
99 JSONScanner m_scanner;
100 MemberContext m_memberContext;
100 MemberContext m_memberContext;
101
101
102 JSONElementType m_elementType;
102 JSONElementType m_elementType;
103 object m_elementValue;
103 object m_elementValue;
104
104
105 /// <summary>
105 /// <summary>
106 /// Создает новый парсер на основе строки, содержащей JSON
106 /// Создает новый парсер на основе строки, содержащей JSON
107 /// </summary>
107 /// </summary>
108 /// <param name="text"></param>
108 /// <param name="text"></param>
109 public JSONParser(string text)
109 public JSONParser(string text)
110 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
110 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
111 Safe.ArgumentNotEmpty(text, "text");
111 Safe.ArgumentNotEmpty(text, "text");
112 m_scanner = new JSONScanner();
112 m_scanner = new JSONScanner();
113 m_scanner.Feed(text.ToCharArray());
113 m_scanner.Feed(text.ToCharArray());
114 }
114 }
115
115
116 /// <summary>
116 /// <summary>
117 /// Создает новый экземпляр парсера, на основе текстового потока.
117 /// Создает новый экземпляр парсера, на основе текстового потока.
118 /// </summary>
118 /// </summary>
119 /// <param name="reader">Текстовый поток.</param>
119 /// <param name="reader">Текстовый поток.</param>
120 /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param>
120 /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param>
121 public JSONParser(TextReader reader, bool dispose)
121 public JSONParser(TextReader reader, bool dispose)
122 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
122 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
123 Safe.ArgumentNotNull(reader, "reader");
123 Safe.ArgumentNotNull(reader, "reader");
124 m_scanner = new JSONScanner();
124 m_scanner = new JSONScanner();
125 m_scanner.Feed(reader, dispose);
125 m_scanner.Feed(reader, dispose);
126 }
126 }
127
127
128 /// <summary>
128 /// <summary>
129 /// Тип текущего элемента на котором стоит парсер.
129 /// Тип текущего элемента на котором стоит парсер.
130 /// </summary>
130 /// </summary>
131 public JSONElementType ElementType {
131 public JSONElementType ElementType {
132 get { return m_elementType; }
132 get { return m_elementType; }
133 }
133 }
134
134
135 /// <summary>
135 /// <summary>
136 /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
136 /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
137 /// пустая строка.
137 /// пустая строка.
138 /// </summary>
138 /// </summary>
139 public string ElementName {
139 public string ElementName {
140 get { return m_context.info.memberName; }
140 get { return m_context.info.memberName; }
141 }
141 }
142
142
143 /// <summary>
143 /// <summary>
144 /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c>
144 /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c>
145 /// </summary>
145 /// </summary>
146 public object ElementValue {
146 public object ElementValue {
147 get { return m_elementValue; }
147 get { return m_elementValue; }
148 }
148 }
149
149
150 /// <summary>
150 /// <summary>
151 /// Читает слеюудущий объект из потока
151 /// Читает слеюудущий объект из потока
152 /// </summary>
152 /// </summary>
153 /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns>
153 /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns>
154 public bool Read() {
154 public bool Read() {
155 if (m_context.current == UNREACHEBLE_STATE)
155 if (m_context.current == UNREACHEBLE_STATE)
156 throw new InvalidOperationException("The parser is in invalid state");
156 throw new InvalidOperationException("The parser is in invalid state");
157 object tokenValue;
157 object tokenValue;
158 JsonTokenType tokenType;
158 JsonTokenType tokenType;
159 m_context.info.memberName = String.Empty;
159 m_context.info.memberName = String.Empty;
160 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
160 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
161 Move((int)tokenType);
161 Move((int)tokenType);
162 if (m_context.current == UNREACHEBLE_STATE)
162 if (m_context.current == UNREACHEBLE_STATE)
163 UnexpectedToken(tokenValue, tokenType);
163 UnexpectedToken(tokenValue, tokenType);
164 switch (tokenType) {
164 switch (tokenType) {
165 case JsonTokenType.BeginObject:
165 case JsonTokenType.BeginObject:
166 Switch(
166 Switch(
167 _objectDFA,
167 _objectDFA,
168 INITIAL_STATE,
168 INITIAL_STATE,
169 new JSONParserContext {
169 new JSONParserContext {
170 memberName = m_context.info.memberName,
170 memberName = m_context.info.memberName,
171 elementContext = JSONElementContext.Object
171 elementContext = JSONElementContext.Object
172 }
172 }
173 );
173 );
174 m_elementValue = null;
174 m_elementValue = null;
175 m_memberContext = MemberContext.MemberName;
175 m_memberContext = MemberContext.MemberName;
176 m_elementType = JSONElementType.BeginObject;
176 m_elementType = JSONElementType.BeginObject;
177 return true;
177 return true;
178 case JsonTokenType.EndObject:
178 case JsonTokenType.EndObject:
179 Restore();
179 Restore();
180 m_elementValue = null;
180 m_elementValue = null;
181 m_elementType = JSONElementType.EndObject;
181 m_elementType = JSONElementType.EndObject;
182 return true;
182 return true;
183 case JsonTokenType.BeginArray:
183 case JsonTokenType.BeginArray:
184 Switch(
184 Switch(
185 _arrayDFA,
185 _arrayDFA,
186 INITIAL_STATE,
186 INITIAL_STATE,
187 new JSONParserContext {
187 new JSONParserContext {
188 memberName = m_context.info.memberName,
188 memberName = m_context.info.memberName,
189 elementContext = JSONElementContext.Array
189 elementContext = JSONElementContext.Array
190 }
190 }
191 );
191 );
192 m_elementValue = null;
192 m_elementValue = null;
193 m_memberContext = MemberContext.MemberValue;
193 m_memberContext = MemberContext.MemberValue;
194 m_elementType = JSONElementType.BeginArray;
194 m_elementType = JSONElementType.BeginArray;
195 return true;
195 return true;
196 case JsonTokenType.EndArray:
196 case JsonTokenType.EndArray:
197 Restore();
197 Restore();
198 m_elementValue = null;
198 m_elementValue = null;
199 m_elementType = JSONElementType.EndArray;
199 m_elementType = JSONElementType.EndArray;
200 return true;
200 return true;
201 case JsonTokenType.String:
201 case JsonTokenType.String:
202 if (m_memberContext == MemberContext.MemberName) {
202 if (m_memberContext == MemberContext.MemberName) {
203 m_context.info.memberName = (string)tokenValue;
203 m_context.info.memberName = (string)tokenValue;
204 break;
204 break;
205 }
205 }
206 m_elementType = JSONElementType.Value;
206 m_elementType = JSONElementType.Value;
207 m_elementValue = tokenValue;
207 m_elementValue = tokenValue;
208 return true;
208 return true;
209 case JsonTokenType.Number:
209 case JsonTokenType.Number:
210 m_elementType = JSONElementType.Value;
210 m_elementType = JSONElementType.Value;
211 m_elementValue = tokenValue;
211 m_elementValue = tokenValue;
212 return true;
212 return true;
213 case JsonTokenType.Literal:
213 case JsonTokenType.Literal:
214 m_elementType = JSONElementType.Value;
214 m_elementType = JSONElementType.Value;
215 m_elementValue = ParseLiteral((string)tokenValue);
215 m_elementValue = ParseLiteral((string)tokenValue);
216 return true;
216 return true;
217 case JsonTokenType.NameSeparator:
217 case JsonTokenType.NameSeparator:
218 m_memberContext = MemberContext.MemberValue;
218 m_memberContext = MemberContext.MemberValue;
219 break;
219 break;
220 case JsonTokenType.ValueSeparator:
220 case JsonTokenType.ValueSeparator:
221 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
221 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
222 break;
222 break;
223 default:
223 default:
224 UnexpectedToken(tokenValue, tokenType);
224 UnexpectedToken(tokenValue, tokenType);
225 break;
225 break;
226 }
226 }
227 }
227 }
228 if (m_context.info.elementContext != JSONElementContext.None)
228 if (m_context.info.elementContext != JSONElementContext.None)
229 throw new ParserException("Unexpedted end of data");
229 throw new ParserException("Unexpedted end of data");
230 return false;
230 return false;
231 }
231 }
232
232
233 object ParseLiteral(string literal) {
233 object ParseLiteral(string literal) {
234 switch (literal) {
234 switch (literal) {
235 case "null":
235 case "null":
236 return null;
236 return null;
237 case "false":
237 case "false":
238 return false;
238 return false;
239 case "true":
239 case "true":
240 return true;
240 return true;
241 default:
241 default:
242 UnexpectedToken(literal, JsonTokenType.Literal);
242 UnexpectedToken(literal, JsonTokenType.Literal);
243 return null; // avoid compliler error
243 return null; // avoid compliler error
244 }
244 }
245 }
245 }
246
246
247 void UnexpectedToken(object value, JsonTokenType tokenType) {
247 void UnexpectedToken(object value, JsonTokenType tokenType) {
248 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
248 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
249 }
249 }
250
250
251
251
252 /// <summary>
252 /// <summary>
253 /// Признак конца потока
253 /// Признак конца потока
254 /// </summary>
254 /// </summary>
255 public bool EOF {
255 public bool EOF {
256 get {
256 get {
257 return m_scanner.EOF;
257 return m_scanner.EOF;
258 }
258 }
259 }
259 }
260
260
261 protected override void Dispose(bool disposing) {
261 protected override void Dispose(bool disposing) {
262 if (disposing) {
262 if (disposing) {
263 m_scanner.Dispose();
263 m_scanner.Dispose();
264 }
264 }
265 }
265 }
266
266
267 /// <summary>
267 /// <summary>
268 /// Переходит в конец текущего объекта.
268 /// Переходит в конец текущего объекта.
269 /// </summary>
269 /// </summary>
270 public void SeekElementEnd() {
270 public void SeekElementEnd() {
271 var level = Level - 1;
271 var level = Level - 1;
272
272
273 Debug.Assert(level >= 0);
273 Debug.Assert(level >= 0);
274
274
275 while (Level != level)
275 while (Level != level)
276 Read();
276 Read();
277 }
277 }
278 }
278 }
279
279
280 }
280 }
@@ -1,272 +1,272
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
10 <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
11 <ReleaseVersion>0.2</ReleaseVersion>
11 <ReleaseVersion>0.2</ReleaseVersion>
12 <ProductVersion>8.0.30703</ProductVersion>
12 <ProductVersion>8.0.30703</ProductVersion>
13 <SchemaVersion>2.0</SchemaVersion>
13 <SchemaVersion>2.0</SchemaVersion>
14 </PropertyGroup>
14 </PropertyGroup>
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
15 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
16 <DebugSymbols>true</DebugSymbols>
16 <DebugSymbols>true</DebugSymbols>
17 <DebugType>full</DebugType>
17 <DebugType>full</DebugType>
18 <Optimize>false</Optimize>
18 <Optimize>false</Optimize>
19 <OutputPath>bin\Debug</OutputPath>
19 <OutputPath>bin\Debug</OutputPath>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
20 <DefineConstants>TRACE;DEBUG;</DefineConstants>
21 <ErrorReport>prompt</ErrorReport>
21 <ErrorReport>prompt</ErrorReport>
22 <WarningLevel>4</WarningLevel>
22 <WarningLevel>4</WarningLevel>
23 <ConsolePause>false</ConsolePause>
23 <ConsolePause>false</ConsolePause>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
24 <RunCodeAnalysis>true</RunCodeAnalysis>
25 </PropertyGroup>
25 </PropertyGroup>
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27 <DebugType>full</DebugType>
27 <DebugType>full</DebugType>
28 <Optimize>true</Optimize>
28 <Optimize>true</Optimize>
29 <OutputPath>bin\Release</OutputPath>
29 <OutputPath>bin\Release</OutputPath>
30 <ErrorReport>prompt</ErrorReport>
30 <ErrorReport>prompt</ErrorReport>
31 <WarningLevel>4</WarningLevel>
31 <WarningLevel>4</WarningLevel>
32 <ConsolePause>false</ConsolePause>
32 <ConsolePause>false</ConsolePause>
33 </PropertyGroup>
33 </PropertyGroup>
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
34 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
35 <DebugSymbols>true</DebugSymbols>
35 <DebugSymbols>true</DebugSymbols>
36 <DebugType>full</DebugType>
36 <DebugType>full</DebugType>
37 <Optimize>false</Optimize>
37 <Optimize>false</Optimize>
38 <OutputPath>bin\Debug</OutputPath>
38 <OutputPath>bin\Debug</OutputPath>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
39 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
40 <ErrorReport>prompt</ErrorReport>
40 <ErrorReport>prompt</ErrorReport>
41 <WarningLevel>4</WarningLevel>
41 <WarningLevel>4</WarningLevel>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
42 <RunCodeAnalysis>true</RunCodeAnalysis>
43 <ConsolePause>false</ConsolePause>
43 <ConsolePause>false</ConsolePause>
44 </PropertyGroup>
44 </PropertyGroup>
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
46 <Optimize>true</Optimize>
46 <Optimize>true</Optimize>
47 <OutputPath>bin\Release</OutputPath>
47 <OutputPath>bin\Release</OutputPath>
48 <ErrorReport>prompt</ErrorReport>
48 <ErrorReport>prompt</ErrorReport>
49 <WarningLevel>4</WarningLevel>
49 <WarningLevel>4</WarningLevel>
50 <ConsolePause>false</ConsolePause>
50 <ConsolePause>false</ConsolePause>
51 <DefineConstants>NET_4_5</DefineConstants>
51 <DefineConstants>NET_4_5</DefineConstants>
52 </PropertyGroup>
52 </PropertyGroup>
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
53 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
54 <DebugSymbols>true</DebugSymbols>
54 <DebugSymbols>true</DebugSymbols>
55 <DebugType>full</DebugType>
55 <DebugType>full</DebugType>
56 <Optimize>false</Optimize>
56 <Optimize>false</Optimize>
57 <OutputPath>bin\Debug</OutputPath>
57 <OutputPath>bin\Debug</OutputPath>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
58 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
59 <ErrorReport>prompt</ErrorReport>
59 <ErrorReport>prompt</ErrorReport>
60 <WarningLevel>4</WarningLevel>
60 <WarningLevel>4</WarningLevel>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
61 <RunCodeAnalysis>true</RunCodeAnalysis>
62 <ConsolePause>false</ConsolePause>
62 <ConsolePause>false</ConsolePause>
63 </PropertyGroup>
63 </PropertyGroup>
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
64 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
65 <Optimize>true</Optimize>
65 <Optimize>true</Optimize>
66 <OutputPath>bin\Release</OutputPath>
66 <OutputPath>bin\Release</OutputPath>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
67 <DefineConstants>NET_4_5;MONO;</DefineConstants>
68 <ErrorReport>prompt</ErrorReport>
68 <ErrorReport>prompt</ErrorReport>
69 <WarningLevel>4</WarningLevel>
69 <WarningLevel>4</WarningLevel>
70 <ConsolePause>false</ConsolePause>
70 <ConsolePause>false</ConsolePause>
71 </PropertyGroup>
71 </PropertyGroup>
72 <ItemGroup>
72 <ItemGroup>
73 <Reference Include="System" />
73 <Reference Include="System" />
74 <Reference Include="System.Xml" />
74 <Reference Include="System.Xml" />
75 <Reference Include="mscorlib" />
75 <Reference Include="mscorlib" />
76 </ItemGroup>
76 </ItemGroup>
77 <ItemGroup>
77 <ItemGroup>
78 <Compile Include="CustomEqualityComparer.cs" />
78 <Compile Include="CustomEqualityComparer.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
79 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
80 <Compile Include="Diagnostics\EventText.cs" />
80 <Compile Include="Diagnostics\EventText.cs" />
81 <Compile Include="Diagnostics\LogChannel.cs" />
81 <Compile Include="Diagnostics\LogChannel.cs" />
82 <Compile Include="Diagnostics\LogicalOperation.cs" />
82 <Compile Include="Diagnostics\LogicalOperation.cs" />
83 <Compile Include="Diagnostics\TextFileListener.cs" />
83 <Compile Include="Diagnostics\TextFileListener.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
84 <Compile Include="Diagnostics\TraceLog.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
85 <Compile Include="Diagnostics\TraceEvent.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
86 <Compile Include="Diagnostics\TraceEventType.cs" />
87 <Compile Include="ICancellable.cs" />
87 <Compile Include="ICancellable.cs" />
88 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressHandler.cs" />
89 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IProgressNotifier.cs" />
90 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromiseT.cs" />
91 <Compile Include="IPromise.cs" />
91 <Compile Include="IPromise.cs" />
92 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="IServiceLocator.cs" />
93 <Compile Include="ITaskController.cs" />
93 <Compile Include="ITaskController.cs" />
94 <Compile Include="Parallels\DispatchPool.cs" />
94 <Compile Include="Parallels\DispatchPool.cs" />
95 <Compile Include="Parallels\ArrayTraits.cs" />
95 <Compile Include="Parallels\ArrayTraits.cs" />
96 <Compile Include="Parallels\MTQueue.cs" />
96 <Compile Include="Parallels\MTQueue.cs" />
97 <Compile Include="Parallels\WorkerPool.cs" />
97 <Compile Include="Parallels\WorkerPool.cs" />
98 <Compile Include="ProgressInitEventArgs.cs" />
98 <Compile Include="ProgressInitEventArgs.cs" />
99 <Compile Include="Properties\AssemblyInfo.cs" />
99 <Compile Include="Properties\AssemblyInfo.cs" />
100 <Compile Include="Parallels\AsyncPool.cs" />
100 <Compile Include="Parallels\AsyncPool.cs" />
101 <Compile Include="Safe.cs" />
101 <Compile Include="Safe.cs" />
102 <Compile Include="ValueEventArgs.cs" />
102 <Compile Include="ValueEventArgs.cs" />
103 <Compile Include="PromiseExtensions.cs" />
103 <Compile Include="PromiseExtensions.cs" />
104 <Compile Include="SyncContextPromise.cs" />
104 <Compile Include="SyncContextPromise.cs" />
105 <Compile Include="Diagnostics\OperationContext.cs" />
105 <Compile Include="Diagnostics\OperationContext.cs" />
106 <Compile Include="Diagnostics\TraceContext.cs" />
106 <Compile Include="Diagnostics\TraceContext.cs" />
107 <Compile Include="Diagnostics\LogEventArgs.cs" />
107 <Compile Include="Diagnostics\LogEventArgs.cs" />
108 <Compile Include="Diagnostics\LogEventArgsT.cs" />
108 <Compile Include="Diagnostics\LogEventArgsT.cs" />
109 <Compile Include="Diagnostics\Extensions.cs" />
109 <Compile Include="Diagnostics\Extensions.cs" />
110 <Compile Include="PromiseEventType.cs" />
110 <Compile Include="PromiseEventType.cs" />
111 <Compile Include="Parallels\AsyncQueue.cs" />
111 <Compile Include="Parallels\AsyncQueue.cs" />
112 <Compile Include="PromiseT.cs" />
112 <Compile Include="PromiseT.cs" />
113 <Compile Include="IDeferred.cs" />
113 <Compile Include="IDeferred.cs" />
114 <Compile Include="IDeferredT.cs" />
114 <Compile Include="IDeferredT.cs" />
115 <Compile Include="Promise.cs" />
115 <Compile Include="Promise.cs" />
116 <Compile Include="PromiseTransientException.cs" />
116 <Compile Include="PromiseTransientException.cs" />
117 <Compile Include="Parallels\Signal.cs" />
117 <Compile Include="Parallels\Signal.cs" />
118 <Compile Include="Parallels\SharedLock.cs" />
118 <Compile Include="Parallels\SharedLock.cs" />
119 <Compile Include="Diagnostics\ILogWriter.cs" />
119 <Compile Include="Diagnostics\ILogWriter.cs" />
120 <Compile Include="Diagnostics\ListenerBase.cs" />
120 <Compile Include="Diagnostics\ListenerBase.cs" />
121 <Compile Include="Parallels\BlockingQueue.cs" />
121 <Compile Include="Parallels\BlockingQueue.cs" />
122 <Compile Include="AbstractEvent.cs" />
122 <Compile Include="AbstractEvent.cs" />
123 <Compile Include="AbstractPromise.cs" />
123 <Compile Include="AbstractPromise.cs" />
124 <Compile Include="AbstractPromiseT.cs" />
124 <Compile Include="AbstractPromiseT.cs" />
125 <Compile Include="FuncTask.cs" />
125 <Compile Include="FuncTask.cs" />
126 <Compile Include="FuncTaskBase.cs" />
126 <Compile Include="FuncTaskBase.cs" />
127 <Compile Include="FuncTaskT.cs" />
127 <Compile Include="FuncTaskT.cs" />
128 <Compile Include="ActionChainTaskBase.cs" />
128 <Compile Include="ActionChainTaskBase.cs" />
129 <Compile Include="ActionChainTask.cs" />
129 <Compile Include="ActionChainTask.cs" />
130 <Compile Include="ActionChainTaskT.cs" />
130 <Compile Include="ActionChainTaskT.cs" />
131 <Compile Include="FuncChainTaskBase.cs" />
131 <Compile Include="FuncChainTaskBase.cs" />
132 <Compile Include="FuncChainTask.cs" />
132 <Compile Include="FuncChainTask.cs" />
133 <Compile Include="FuncChainTaskT.cs" />
133 <Compile Include="FuncChainTaskT.cs" />
134 <Compile Include="ActionTaskBase.cs" />
134 <Compile Include="ActionTaskBase.cs" />
135 <Compile Include="ActionTask.cs" />
135 <Compile Include="ActionTask.cs" />
136 <Compile Include="ActionTaskT.cs" />
136 <Compile Include="ActionTaskT.cs" />
137 <Compile Include="ICancellationToken.cs" />
137 <Compile Include="ICancellationToken.cs" />
138 <Compile Include="SuccessPromise.cs" />
138 <Compile Include="SuccessPromise.cs" />
139 <Compile Include="SuccessPromiseT.cs" />
139 <Compile Include="SuccessPromiseT.cs" />
140 <Compile Include="PromiseAwaiterT.cs" />
140 <Compile Include="PromiseAwaiterT.cs" />
141 <Compile Include="PromiseAwaiter.cs" />
141 <Compile Include="PromiseAwaiter.cs" />
142 <Compile Include="Components\ComponentContainer.cs" />
142 <Compile Include="Components\ComponentContainer.cs" />
143 <Compile Include="Components\Disposable.cs" />
143 <Compile Include="Components\Disposable.cs" />
144 <Compile Include="Components\DisposablePool.cs" />
144 <Compile Include="Components\DisposablePool.cs" />
145 <Compile Include="Components\ObjectPool.cs" />
145 <Compile Include="Components\ObjectPool.cs" />
146 <Compile Include="Components\ServiceLocator.cs" />
146 <Compile Include="Components\ServiceLocator.cs" />
147 <Compile Include="Components\IInitializable.cs" />
147 <Compile Include="Components\IInitializable.cs" />
148 <Compile Include="TaskController.cs" />
148 <Compile Include="TaskController.cs" />
149 <Compile Include="Components\App.cs" />
149 <Compile Include="Components\App.cs" />
150 <Compile Include="Components\IRunnable.cs" />
150 <Compile Include="Components\IRunnable.cs" />
151 <Compile Include="Components\ExecutionState.cs" />
151 <Compile Include="Components\ExecutionState.cs" />
152 <Compile Include="Components\RunnableComponent.cs" />
152 <Compile Include="Components\RunnableComponent.cs" />
153 <Compile Include="Components\IFactory.cs" />
153 <Compile Include="Components\IFactory.cs" />
154 <Compile Include="Automaton\DFAStateDescriptor.cs" />
154 <Compile Include="Automaton\DFAStateDescriptor.cs" />
155 <Compile Include="Automaton\EnumAlphabet.cs" />
155 <Compile Include="Automaton\EnumAlphabet.cs" />
156 <Compile Include="Automaton\IAlphabet.cs" />
156 <Compile Include="Automaton\IAlphabet.cs" />
157 <Compile Include="Automaton\ParserException.cs" />
157 <Compile Include="Automaton\ParserException.cs" />
158 <Compile Include="Automaton\Scanner.cs" />
158 <Compile Include="Automaton\Scanner.cs" />
159 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
159 <Compile Include="Automaton\IndexedAlphabetBase.cs" />
160 <Compile Include="Automaton\IAlphabetBuilder.cs" />
160 <Compile Include="Automaton\IAlphabetBuilder.cs" />
161 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
161 <Compile Include="Automaton\RegularExpressions\AltToken.cs" />
162 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
162 <Compile Include="Automaton\RegularExpressions\BinaryToken.cs" />
163 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
163 <Compile Include="Automaton\RegularExpressions\CatToken.cs" />
164 <Compile Include="Automaton\DFAConst.cs" />
164 <Compile Include="Automaton\DFAConst.cs" />
165 <Compile Include="Automaton\RegularExpressions\Grammar.cs" />
165 <Compile Include="Automaton\RegularExpressions\Grammar.cs" />
166 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
166 <Compile Include="Automaton\RegularExpressions\StarToken.cs" />
167 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
167 <Compile Include="Automaton\RegularExpressions\SymbolToken.cs" />
168 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
168 <Compile Include="Automaton\RegularExpressions\EmptyToken.cs" />
169 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
169 <Compile Include="Automaton\RegularExpressions\EndToken.cs" />
170 <Compile Include="Automaton\RegularExpressions\Token.cs" />
170 <Compile Include="Automaton\RegularExpressions\Token.cs" />
171 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
171 <Compile Include="Automaton\RegularExpressions\IVisitor.cs" />
172 <Compile Include="Automaton\AutomatonTransition.cs" />
172 <Compile Include="Automaton\AutomatonTransition.cs" />
173 <Compile Include="Automaton\RegularExpressions\RegularDFABuilder.cs" />
174 <Compile Include="Formats\JSON\JSONElementContext.cs" />
173 <Compile Include="Formats\JSON\JSONElementContext.cs" />
175 <Compile Include="Formats\JSON\JSONElementType.cs" />
174 <Compile Include="Formats\JSON\JSONElementType.cs" />
176 <Compile Include="Formats\JSON\JSONGrammar.cs" />
175 <Compile Include="Formats\JSON\JSONGrammar.cs" />
177 <Compile Include="Formats\JSON\JSONParser.cs" />
176 <Compile Include="Formats\JSON\JSONParser.cs" />
178 <Compile Include="Formats\JSON\JSONScanner.cs" />
177 <Compile Include="Formats\JSON\JSONScanner.cs" />
179 <Compile Include="Formats\JSON\JsonTokenType.cs" />
178 <Compile Include="Formats\JSON\JsonTokenType.cs" />
180 <Compile Include="Formats\JSON\JSONWriter.cs" />
179 <Compile Include="Formats\JSON\JSONWriter.cs" />
181 <Compile Include="Formats\JSON\JSONXmlReader.cs" />
180 <Compile Include="Formats\JSON\JSONXmlReader.cs" />
182 <Compile Include="Formats\JSON\JSONXmlReaderOptions.cs" />
181 <Compile Include="Formats\JSON\JSONXmlReaderOptions.cs" />
183 <Compile Include="Formats\JSON\StringTranslator.cs" />
182 <Compile Include="Formats\JSON\StringTranslator.cs" />
184 <Compile Include="Automaton\MapAlphabet.cs" />
183 <Compile Include="Automaton\MapAlphabet.cs" />
185 <Compile Include="Automaton\DummyAlphabet.cs" />
184 <Compile Include="Automaton\DummyAlphabet.cs" />
186 <Compile Include="Automaton\RegularExpressions\RegularDFADefinition.cs" />
187 <Compile Include="Formats\CharAlphabet.cs" />
185 <Compile Include="Formats\CharAlphabet.cs" />
188 <Compile Include="Formats\ByteAlphabet.cs" />
186 <Compile Include="Formats\ByteAlphabet.cs" />
189 <Compile Include="Formats\RegularCharDFADefinition.cs" />
190 <Compile Include="Automaton\IDFATable.cs" />
187 <Compile Include="Automaton\IDFATable.cs" />
191 <Compile Include="Automaton\IDFATableBuilder.cs" />
188 <Compile Include="Automaton\IDFATableBuilder.cs" />
192 <Compile Include="Automaton\DFATable.cs" />
189 <Compile Include="Automaton\DFATable.cs" />
190 <Compile Include="Automaton\RegularExpressions\RegularDFA.cs" />
191 <Compile Include="Automaton\RegularExpressions\RegularExpressionVisitor.cs" />
192 <Compile Include="Automaton\RegularExpressions\ITaggedDFABuilder.cs" />
193 <Compile Include="Automaton\RegularExpressions\DFAStateDescriptorT.cs" />
193 <Compile Include="Automaton\RegularExpressions\DFAStateDescriptorT.cs" />
194 </ItemGroup>
194 </ItemGroup>
195 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
195 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
196 <ItemGroup />
196 <ItemGroup />
197 <ProjectExtensions>
197 <ProjectExtensions>
198 <MonoDevelop>
198 <MonoDevelop>
199 <Properties>
199 <Properties>
200 <Policies>
200 <Policies>
201 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
201 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
202 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
202 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
203 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
203 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
204 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
204 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
205 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
205 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
206 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
206 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
207 <NameConventionPolicy>
207 <NameConventionPolicy>
208 <Rules>
208 <Rules>
209 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
209 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
211 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
211 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
212 <RequiredPrefixes>
212 <RequiredPrefixes>
213 <String>I</String>
213 <String>I</String>
214 </RequiredPrefixes>
214 </RequiredPrefixes>
215 </NamingRule>
215 </NamingRule>
216 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
216 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
217 <RequiredSuffixes>
217 <RequiredSuffixes>
218 <String>Attribute</String>
218 <String>Attribute</String>
219 </RequiredSuffixes>
219 </RequiredSuffixes>
220 </NamingRule>
220 </NamingRule>
221 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
221 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
222 <RequiredSuffixes>
222 <RequiredSuffixes>
223 <String>EventArgs</String>
223 <String>EventArgs</String>
224 </RequiredSuffixes>
224 </RequiredSuffixes>
225 </NamingRule>
225 </NamingRule>
226 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
226 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
227 <RequiredSuffixes>
227 <RequiredSuffixes>
228 <String>Exception</String>
228 <String>Exception</String>
229 </RequiredSuffixes>
229 </RequiredSuffixes>
230 </NamingRule>
230 </NamingRule>
231 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
231 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
232 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
232 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
233 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
233 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
234 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
234 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
235 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
235 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
236 <RequiredPrefixes>
236 <RequiredPrefixes>
237 <String>m_</String>
237 <String>m_</String>
238 </RequiredPrefixes>
238 </RequiredPrefixes>
239 </NamingRule>
239 </NamingRule>
240 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
240 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
241 <RequiredPrefixes>
241 <RequiredPrefixes>
242 <String>_</String>
242 <String>_</String>
243 </RequiredPrefixes>
243 </RequiredPrefixes>
244 </NamingRule>
244 </NamingRule>
245 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
245 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
246 <RequiredPrefixes>
246 <RequiredPrefixes>
247 <String>m_</String>
247 <String>m_</String>
248 </RequiredPrefixes>
248 </RequiredPrefixes>
249 </NamingRule>
249 </NamingRule>
250 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
250 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
251 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
251 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
252 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
252 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
253 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
253 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
254 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
254 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
255 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
255 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
256 <RequiredPrefixes>
256 <RequiredPrefixes>
257 <String>T</String>
257 <String>T</String>
258 </RequiredPrefixes>
258 </RequiredPrefixes>
259 </NamingRule>
259 </NamingRule>
260 </Rules>
260 </Rules>
261 </NameConventionPolicy>
261 </NameConventionPolicy>
262 </Policies>
262 </Policies>
263 </Properties>
263 </Properties>
264 </MonoDevelop>
264 </MonoDevelop>
265 </ProjectExtensions>
265 </ProjectExtensions>
266 <ItemGroup>
266 <ItemGroup>
267 <Folder Include="Components\" />
267 <Folder Include="Components\" />
268 <Folder Include="Automaton\RegularExpressions\" />
268 <Folder Include="Automaton\RegularExpressions\" />
269 <Folder Include="Formats\" />
269 <Folder Include="Formats\" />
270 <Folder Include="Formats\JSON\" />
270 <Folder Include="Formats\JSON\" />
271 </ItemGroup>
271 </ItemGroup>
272 </Project> No newline at end of file
272 </Project>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now