##// END OF EJS Templates
Added Skip method to JSON parser to skip contents of the current node
cin -
r62:62b440d46313 default
parent child
Show More
@@ -1,255 +1,264
1 using Implab;
1 using Implab;
2 using Implab.Parsing;
2 using Implab.Parsing;
3 using System;
3 using System;
4 using System.Collections.Generic;
4 using System.Collections.Generic;
5 using System.Diagnostics;
5 using System.Diagnostics;
6 using System.IO;
6 using System.IO;
7 using System.Linq;
7 using System.Linq;
8 using System.Text;
8 using System.Text;
9 using System.Threading.Tasks;
9 using System.Threading.Tasks;
10
10
11 namespace Implab.JSON {
11 namespace Implab.JSON {
12 /// <summary>
12 /// <summary>
13 /// internal
13 /// internal
14 /// </summary>
14 /// </summary>
15 public struct JSONParserContext {
15 public struct JSONParserContext {
16 public string memberName;
16 public string memberName;
17 public JSONElementContext elementContext;
17 public JSONElementContext elementContext;
18 }
18 }
19
19
20 /// <summary>
20 /// <summary>
21 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
21 /// Pull парсСр JSON Π΄Π°Π½Π½Ρ‹Ρ….
22 /// </summary>
22 /// </summary>
23 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
23 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
24
24
25 enum MemberContext {
25 enum MemberContext {
26 MemberName,
26 MemberName,
27 MemberValue
27 MemberValue
28 }
28 }
29
29
30 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
30 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
31 static readonly DFAStateDescriptior[] _jsonDFA;
31 static readonly DFAStateDescriptior[] _jsonDFA;
32 static readonly DFAStateDescriptior[] _objectDFA;
32 static readonly DFAStateDescriptior[] _objectDFA;
33 static readonly DFAStateDescriptior[] _arrayDFA;
33 static readonly DFAStateDescriptior[] _arrayDFA;
34
34
35 static JSONParser() {
35 static JSONParser() {
36 var jsonExpression = Token.New(JsonTokenType.BeginObject, JsonTokenType.BeginArray).Tag(0);
36 var jsonExpression = Token.New(JsonTokenType.BeginObject, JsonTokenType.BeginArray).Tag(0);
37
37
38 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
38 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
39 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
39 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
40 var objectExpression = memberExpression
40 var objectExpression = memberExpression
41 .Cat(
41 .Cat(
42 Token.New(JsonTokenType.ValueSeparator)
42 Token.New(JsonTokenType.ValueSeparator)
43 .Cat(memberExpression)
43 .Cat(memberExpression)
44 .EClosure()
44 .EClosure()
45 )
45 )
46 .Optional()
46 .Optional()
47 .Cat(Token.New(JsonTokenType.EndObject))
47 .Cat(Token.New(JsonTokenType.EndObject))
48 .Tag(0);
48 .Tag(0);
49 var arrayExpression = valueExpression
49 var arrayExpression = valueExpression
50 .Cat(
50 .Cat(
51 Token.New(JsonTokenType.ValueSeparator)
51 Token.New(JsonTokenType.ValueSeparator)
52 .Cat(valueExpression)
52 .Cat(valueExpression)
53 .EClosure()
53 .EClosure()
54 )
54 )
55 .Optional()
55 .Optional()
56 .Cat(Token.New(JsonTokenType.EndArray))
56 .Cat(Token.New(JsonTokenType.EndArray))
57 .Tag(0);
57 .Tag(0);
58
58
59 _jsonDFA = BuildDFA(jsonExpression).States;
59 _jsonDFA = BuildDFA(jsonExpression).States;
60 _objectDFA = BuildDFA(objectExpression).States;
60 _objectDFA = BuildDFA(objectExpression).States;
61 _arrayDFA = BuildDFA(arrayExpression).States;
61 _arrayDFA = BuildDFA(arrayExpression).States;
62 }
62 }
63
63
64 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
64 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
65 var builder = new DFABuilder();
65 var builder = new DFABuilder();
66 var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
66 var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
67 expr.Accept(builder);
67 expr.Accept(builder);
68
68
69 builder.BuildDFA(dfa);
69 builder.BuildDFA(dfa);
70 return dfa;
70 return dfa;
71 }
71 }
72
72
73 JSONScanner m_scanner;
73 JSONScanner m_scanner;
74 MemberContext m_memberContext;
74 MemberContext m_memberContext;
75
75
76 JSONElementType m_elementType;
76 JSONElementType m_elementType;
77 object m_elementValue;
77 object m_elementValue;
78
78
79 /// <summary>
79 /// <summary>
80 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
80 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ парсСр Π½Π° основС строки, содСрТащСй JSON
81 /// </summary>
81 /// </summary>
82 /// <param name="text"></param>
82 /// <param name="text"></param>
83 public JSONParser(string text)
83 public JSONParser(string text)
84 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
84 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
85 Safe.ArgumentNotEmpty(text, "text");
85 Safe.ArgumentNotEmpty(text, "text");
86 m_scanner = new JSONScanner();
86 m_scanner = new JSONScanner();
87 m_scanner.Feed(text.ToCharArray());
87 m_scanner.Feed(text.ToCharArray());
88 }
88 }
89
89
90 /// <summary>
90 /// <summary>
91 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
91 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр парсСра, Π½Π° основС тСкстового ΠΏΠΎΡ‚ΠΎΠΊΠ°.
92 /// </summary>
92 /// </summary>
93 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
93 /// <param name="reader">ВСкстовый ΠΏΠΎΡ‚ΠΎΠΊ.</param>
94 /// <param name="dispose">ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ парсСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠΎΠ½Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ врСмя ΠΆΠΈΠ·Π½ΠΈ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.</param>
94 /// <param name="dispose">ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ парсСр Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠΎΠ½Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ врСмя ΠΆΠΈΠ·Π½ΠΈ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.</param>
95 public JSONParser(TextReader reader, bool dispose)
95 public JSONParser(TextReader reader, bool dispose)
96 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
96 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
97 Safe.ArgumentNotNull(reader, "reader");
97 Safe.ArgumentNotNull(reader, "reader");
98 m_scanner = new JSONScanner();
98 m_scanner = new JSONScanner();
99 m_scanner.Feed(reader, dispose);
99 m_scanner.Feed(reader, dispose);
100 }
100 }
101
101
102 /// <summary>
102 /// <summary>
103 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
103 /// Π’ΠΈΠΏ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ элСмСнта Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стоит парсСр.
104 /// </summary>
104 /// </summary>
105 public JSONElementType ElementType {
105 public JSONElementType ElementType {
106 get { return m_elementType; }
106 get { return m_elementType; }
107 }
107 }
108
108
109 /// <summary>
109 /// <summary>
110 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
110 /// Имя элСмСнта - имя свойства Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Для элСмСнтов массивов ΠΈ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ всСгда
111 /// пустая строка.
111 /// пустая строка.
112 /// </summary>
112 /// </summary>
113 public string ElementName {
113 public string ElementName {
114 get { return m_context.info.memberName; }
114 get { return m_context.info.memberName; }
115 }
115 }
116
116
117 /// <summary>
117 /// <summary>
118 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
118 /// Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта. Волько для элСмСнтов Ρ‚ΠΈΠΏΠ° <see cref="JSONElementType.Value"/>, для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… <c>null</c>
119 /// </summary>
119 /// </summary>
120 public object ElementValue {
120 public object ElementValue {
121 get { return m_elementValue; }
121 get { return m_elementValue; }
122 }
122 }
123
123
124 /// <summary>
124 /// <summary>
125 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
125 /// Π§ΠΈΡ‚Π°Π΅Ρ‚ ΡΠ»Π΅ΡŽΡƒΠ΄ΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ°
126 /// </summary>
126 /// </summary>
127 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
127 /// <returns><c>true</c> - опСрация чтСния ΠΏΡ€ΠΎΡˆΠ»Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ, <c>false</c> - ΠΊΠΎΠ½Π΅Ρ† Π΄Π°Π½Π½Ρ‹Ρ…</returns>
128 public bool Read() {
128 public bool Read() {
129 if (m_context.current == UNREACHEBLE_STATE)
129 if (m_context.current == UNREACHEBLE_STATE)
130 throw new InvalidOperationException("The parser is in invalid state");
130 throw new InvalidOperationException("The parser is in invalid state");
131 object tokenValue;
131 object tokenValue;
132 JsonTokenType tokenType;
132 JsonTokenType tokenType;
133 m_context.info.memberName = String.Empty;
133 m_context.info.memberName = String.Empty;
134 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
134 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
135 Move((int)tokenType);
135 Move((int)tokenType);
136 if (m_context.current == UNREACHEBLE_STATE)
136 if (m_context.current == UNREACHEBLE_STATE)
137 UnexpectedToken(tokenValue, tokenType);
137 UnexpectedToken(tokenValue, tokenType);
138 switch (tokenType) {
138 switch (tokenType) {
139 case JsonTokenType.BeginObject:
139 case JsonTokenType.BeginObject:
140 Switch(
140 Switch(
141 _objectDFA,
141 _objectDFA,
142 INITIAL_STATE,
142 INITIAL_STATE,
143 new JSONParserContext {
143 new JSONParserContext {
144 memberName = m_context.info.memberName,
144 memberName = m_context.info.memberName,
145 elementContext = JSONElementContext.Object
145 elementContext = JSONElementContext.Object
146 }
146 }
147 );
147 );
148 m_elementValue = null;
148 m_elementValue = null;
149 m_memberContext = MemberContext.MemberName;
149 m_memberContext = MemberContext.MemberName;
150 m_elementType = JSONElementType.BeginObject;
150 m_elementType = JSONElementType.BeginObject;
151 return true;
151 return true;
152 case JsonTokenType.EndObject:
152 case JsonTokenType.EndObject:
153 Restore();
153 Restore();
154 m_elementValue = null;
154 m_elementValue = null;
155 m_elementType = JSONElementType.EndObject;
155 m_elementType = JSONElementType.EndObject;
156 return true;
156 return true;
157 case JsonTokenType.BeginArray:
157 case JsonTokenType.BeginArray:
158 Switch(
158 Switch(
159 _arrayDFA,
159 _arrayDFA,
160 INITIAL_STATE,
160 INITIAL_STATE,
161 new JSONParserContext {
161 new JSONParserContext {
162 memberName = m_context.info.memberName,
162 memberName = m_context.info.memberName,
163 elementContext = JSONElementContext.Array
163 elementContext = JSONElementContext.Array
164 }
164 }
165 );
165 );
166 m_elementValue = null;
166 m_elementValue = null;
167 m_memberContext = MemberContext.MemberValue;
167 m_memberContext = MemberContext.MemberValue;
168 m_elementType = JSONElementType.BeginArray;
168 m_elementType = JSONElementType.BeginArray;
169 return true;
169 return true;
170 case JsonTokenType.EndArray:
170 case JsonTokenType.EndArray:
171 Restore();
171 Restore();
172 m_elementValue = null;
172 m_elementValue = null;
173 m_elementType = JSONElementType.EndArray;
173 m_elementType = JSONElementType.EndArray;
174 return true;
174 return true;
175 case JsonTokenType.String:
175 case JsonTokenType.String:
176 if (m_memberContext == MemberContext.MemberName) {
176 if (m_memberContext == MemberContext.MemberName) {
177 m_context.info.memberName = (string)tokenValue;
177 m_context.info.memberName = (string)tokenValue;
178 break;
178 break;
179 } else {
179 } else {
180 m_elementType = JSONElementType.Value;
180 m_elementType = JSONElementType.Value;
181 m_elementValue = tokenValue;
181 m_elementValue = tokenValue;
182 return true;
182 return true;
183 }
183 }
184 case JsonTokenType.Number:
184 case JsonTokenType.Number:
185 m_elementType = JSONElementType.Value;
185 m_elementType = JSONElementType.Value;
186 m_elementValue = tokenValue;
186 m_elementValue = tokenValue;
187 return true;
187 return true;
188 case JsonTokenType.Literal:
188 case JsonTokenType.Literal:
189 m_elementType = JSONElementType.Value;
189 m_elementType = JSONElementType.Value;
190 m_elementValue = ParseLiteral((string)tokenValue);
190 m_elementValue = ParseLiteral((string)tokenValue);
191 return true;
191 return true;
192 case JsonTokenType.NameSeparator:
192 case JsonTokenType.NameSeparator:
193 m_memberContext = MemberContext.MemberValue;
193 m_memberContext = MemberContext.MemberValue;
194 break;
194 break;
195 case JsonTokenType.ValueSeparator:
195 case JsonTokenType.ValueSeparator:
196 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
196 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
197 break;
197 break;
198 default:
198 default:
199 UnexpectedToken(tokenValue, tokenType);
199 UnexpectedToken(tokenValue, tokenType);
200 break;
200 break;
201 }
201 }
202 }
202 }
203 if (m_context.info.elementContext != JSONElementContext.None)
203 if (m_context.info.elementContext != JSONElementContext.None)
204 throw new ParserException("Unexpedted end of data");
204 throw new ParserException("Unexpedted end of data");
205 return false;
205 return false;
206 }
206 }
207
207
208 object ParseLiteral(string literal) {
208 object ParseLiteral(string literal) {
209 switch (literal) {
209 switch (literal) {
210 case "null":
210 case "null":
211 return null;
211 return null;
212 case "false":
212 case "false":
213 return false;
213 return false;
214 case "true":
214 case "true":
215 return true;
215 return true;
216 default:
216 default:
217 UnexpectedToken(literal, JsonTokenType.Literal);
217 UnexpectedToken(literal, JsonTokenType.Literal);
218 return null; // avoid compliler error
218 return null; // avoid compliler error
219 }
219 }
220 }
220 }
221
221
222 void UnexpectedToken(object value, JsonTokenType tokenType) {
222 void UnexpectedToken(object value, JsonTokenType tokenType) {
223 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
223 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
224 }
224 }
225
225
226
226
227 /// <summary>
227 /// <summary>
228 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
228 /// ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°
229 /// </summary>
229 /// </summary>
230 public bool EOF {
230 public bool EOF {
231 get {
231 get {
232 return m_scanner.EOF;
232 return m_scanner.EOF;
233 }
233 }
234 }
234 }
235
235
236 protected virtual void Dispose(bool disposing) {
236 protected virtual void Dispose(bool disposing) {
237 if (disposing) {
237 if (disposing) {
238 m_scanner.Dispose();
238 m_scanner.Dispose();
239 }
239 }
240 }
240 }
241
241
242 /// <summary>
242 /// <summary>
243 /// ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ‚ парсСр ΠΈ связанный с Π½ΠΈΠΌ сканнСр.
243 /// ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ‚ парсСр ΠΈ связанный с Π½ΠΈΠΌ сканнСр.
244 /// </summary>
244 /// </summary>
245 public void Dispose() {
245 public void Dispose() {
246 Dispose(true);
246 Dispose(true);
247 GC.SuppressFinalize(this);
247 GC.SuppressFinalize(this);
248 }
248 }
249
249
250 ~JSONParser() {
250 ~JSONParser() {
251 Dispose(false);
251 Dispose(false);
252 }
252 }
253
254 public void Skip() {
255 var level = Level-1;
256
257 Debug.Assert(level >= 0);
258
259 while (Level != level)
260 Read();
261 }
253 }
262 }
254
263
255 }
264 }
@@ -1,56 +1,56
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 using System.Text;
6 using System.Text;
7 using System.Threading.Tasks;
7 using System.Threading.Tasks;
8
8
9 namespace Implab.Parsing {
9 namespace Implab.Parsing {
10 public abstract class DFAutomaton<T> {
10 public abstract class DFAutomaton<T> {
11 protected struct ContextFrame {
11 protected struct ContextFrame {
12 public DFAStateDescriptior[] states;
12 public DFAStateDescriptior[] states;
13 public int current;
13 public int current;
14 public T info;
14 public T info;
15 }
15 }
16
16
17 public const int INITIAL_STATE = DFADefinitionBase.INITIAL_STATE;
17 public const int INITIAL_STATE = DFADefinitionBase.INITIAL_STATE;
18 public const int UNREACHEBLE_STATE = DFADefinitionBase.UNREACHEBLE_STATE;
18 public const int UNREACHEBLE_STATE = DFADefinitionBase.UNREACHEBLE_STATE;
19
19
20 protected ContextFrame m_context;
20 protected ContextFrame m_context;
21 Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
21 Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
22
22
23 public int Level {
23 protected int Level {
24 get { return m_contextStack.Count; }
24 get { return m_contextStack.Count; }
25 }
25 }
26
26
27 protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
27 protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
28 Safe.ArgumentNotNull(states, "states");
28 Safe.ArgumentNotNull(states, "states");
29 Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
29 Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
30
30
31 m_context.states = states;
31 m_context.states = states;
32 m_context.current = startState;
32 m_context.current = startState;
33 m_context.info = info;
33 m_context.info = info;
34 }
34 }
35
35
36 protected void Switch(DFAStateDescriptior[] states, int current, T info) {
36 protected void Switch(DFAStateDescriptior[] states, int current, T info) {
37 Debug.Assert(states != null);
37 Debug.Assert(states != null);
38 Debug.Assert(current >= 0 && current < states.Length);
38 Debug.Assert(current >= 0 && current < states.Length);
39 m_contextStack.Push(m_context);
39 m_contextStack.Push(m_context);
40 m_context. states = states;
40 m_context. states = states;
41 m_context.current = current;
41 m_context.current = current;
42 m_context.info = info;
42 m_context.info = info;
43 }
43 }
44
44
45 protected void Restore() {
45 protected void Restore() {
46 Debug.Assert(m_contextStack.Count > 0);
46 Debug.Assert(m_contextStack.Count > 0);
47
47
48 m_context = m_contextStack.Pop();
48 m_context = m_contextStack.Pop();
49 }
49 }
50
50
51 protected void Move(int input) {
51 protected void Move(int input) {
52 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
52 Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
53 m_context.current = m_context.states[m_context.current].transitions[input];
53 m_context.current = m_context.states[m_context.current].transitions[input];
54 }
54 }
55 }
55 }
56 }
56 }
General Comments 0
You need to be logged in to leave comments. Login now