annotate Implab/Formats/JSON/JSONParser.cs @ 187:dd4a3590f9c6 ref20160224

Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler Any unhandled OperationCanceledException will cause the promise cancelation
author cin
date Tue, 19 Apr 2016 17:35:20 +0300
parents c32688129f14
children 7d07503621fe
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
1 using System;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
2 using System.Diagnostics;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
3 using System.IO;
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
4 using Implab.Automaton;
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
5 using Implab.Automaton.RegularExpressions;
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
6 using System.Linq;
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
7 using Implab.Components;
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
8 using System.Collections.Generic;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
9
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
10 namespace Implab.Formats.JSON {
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
11 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
12 /// Pull парсер JSON данных.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
13 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
14 /// <remarks>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
15 /// Следует отметить отдельную интерпретацию свойства <see cref="Level"/>,
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
16 /// оно означает текущий уровень вложенности объектов, однако закрывающий
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
17 /// элемент объекта и массива имеет уровень меньше, чем сам объект.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
18 /// <code>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
19 /// { // Level = 1
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
20 /// "name" : "Peter", // Level = 1
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
21 /// "address" : { // Level = 2
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
22 /// city : "Stern" // Level = 2
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
23 /// } // Level = 1
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
24 /// } // Level = 0
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
25 /// </code>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
26 /// </remarks>
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
27 public class JSONParser : Disposable {
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
28
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
29 enum MemberContext {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
30 MemberName,
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
31 MemberValue
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
32 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
33
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
34 #region Parser rules
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
35 struct ParserContext {
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
36 readonly int[,] m_dfa;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
37 int m_state;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
38
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
39 readonly JSONElementContext m_elementContext;
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
40
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
41 public ParserContext(int[,] dfa, int state, JSONElementContext context) {
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
42 m_dfa = dfa;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
43 m_state = state;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
44 m_elementContext = context;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
45 }
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
46
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
47 public bool Move(JsonTokenType token) {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
48 var next = m_dfa[m_state, (int)token];
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
49 if (next == AutomatonConst.UNREACHABLE_STATE)
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
50 return false;
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
51 m_state = next;
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
52 return true;
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
53 }
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
54
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
55 public JSONElementContext ElementContext {
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
56 get { return m_elementContext; }
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
57 }
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
58 }
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
59
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
60 static readonly ParserContext _jsonContext;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
61 static readonly ParserContext _objectContext;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
62 static readonly ParserContext _arrayContext;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
63
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
64 static JSONParser() {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
65
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
66 var valueExpression = MakeToken(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
67 var memberExpression = MakeToken(JsonTokenType.String).Cat(MakeToken(JsonTokenType.NameSeparator)).Cat(valueExpression);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
68
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
69 var objectExpression = memberExpression
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
70 .Cat(
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
71 MakeToken(JsonTokenType.ValueSeparator)
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
72 .Cat(memberExpression)
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
73 .EClosure()
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
74 )
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
75 .Optional()
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
76 .Cat(MakeToken(JsonTokenType.EndObject))
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
77 .End();
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
78
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
79 var arrayExpression = valueExpression
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
80 .Cat(
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
81 MakeToken(JsonTokenType.ValueSeparator)
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
82 .Cat(valueExpression)
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
83 .EClosure()
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
84 )
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
85 .Optional()
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
86 .Cat(MakeToken(JsonTokenType.EndArray))
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
87 .End();
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
88
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
89 var jsonExpression = valueExpression.End();
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
90
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
91 _jsonContext = CreateParserContext(jsonExpression, JSONElementContext.None);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
92 _objectContext = CreateParserContext(objectExpression, JSONElementContext.Object);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
93 _arrayContext = CreateParserContext(arrayExpression, JSONElementContext.Array);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
94 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
95
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
96 static Token MakeToken(params JsonTokenType[] input) {
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
97 return Token.New( input.Select(t => (int)t).ToArray() );
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
98 }
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
99
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
100 static ParserContext CreateParserContext(Token expr, JSONElementContext context) {
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
101
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
102 var dfa = new DFATable();
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
103 var builder = new RegularExpressionVisitor(dfa);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
104 expr.Accept(builder);
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
105 builder.BuildDFA();
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
106
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
107 return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
108 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
109
178
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
110 #endregion
d5c5db0335ee working on JSON parser
cin
parents: 172
diff changeset
111
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
112 readonly JSONScanner m_scanner;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
113 MemberContext m_memberContext;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
114
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
115 JSONElementType m_elementType;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
116 object m_elementValue;
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
117 string m_memberName = String.Empty;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
118
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
119 Stack<ParserContext> m_stack = new Stack<ParserContext>();
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
120 ParserContext m_context = _jsonContext;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
121
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
122 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
123 /// Создает новый парсер на основе строки, содержащей JSON
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
124 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
125 /// <param name="text"></param>
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
126 public JSONParser(string text) {
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
127 Safe.ArgumentNotEmpty(text, "text");
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
128 m_scanner = new JSONScanner(text);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
129 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
130
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
131 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
132 /// Создает новый экземпляр парсера, на основе текстового потока.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
133 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
134 /// <param name="reader">Текстовый поток.</param>
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
135 public JSONParser(TextReader reader) {
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
136 Safe.ArgumentNotNull(reader, "reader");
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
137 m_scanner = new JSONScanner(reader);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
138 }
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
139
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
140 public int Level {
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
141 get { return m_stack.Count; }
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
142 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
143
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
144 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
145 /// Тип текущего элемента на котором стоит парсер.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
146 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
147 public JSONElementType ElementType {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
148 get { return m_elementType; }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
149 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
150
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
151 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
152 /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
153 /// пустая строка.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
154 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
155 public string ElementName {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
156 get { return m_memberName; }
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
157 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
158
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
159 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
160 /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
161 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
162 public object ElementValue {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
163 get { return m_elementValue; }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
164 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
165
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
166 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
167 /// Читает слеюудущий объект из потока
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
168 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
169 /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
170 public bool Read() {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
171 object tokenValue;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
172 JsonTokenType tokenType;
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
173
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
174 m_memberName = String.Empty;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
175
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
176 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
177 if(!m_context.Move(tokenType))
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
178 UnexpectedToken(tokenValue, tokenType);
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
179
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
180 switch (tokenType) {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
181 case JsonTokenType.BeginObject:
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
182 m_stack.Push(m_context);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
183 m_context = _objectContext;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
184
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
185 m_elementValue = null;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
186 m_memberContext = MemberContext.MemberName;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
187 m_elementType = JSONElementType.BeginObject;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
188 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
189 case JsonTokenType.EndObject:
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
190 if (m_stack.Count == 0)
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
191 UnexpectedToken(tokenValue, tokenType);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
192 m_context = m_stack.Pop();
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
193
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
194 m_elementValue = null;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
195 m_elementType = JSONElementType.EndObject;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
196 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
197 case JsonTokenType.BeginArray:
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
198 m_stack.Push(m_context);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
199 m_context = _arrayContext;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
200
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
201 m_elementValue = null;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
202 m_memberContext = MemberContext.MemberValue;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
203 m_elementType = JSONElementType.BeginArray;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
204 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
205 case JsonTokenType.EndArray:
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
206 if (m_stack.Count == 0)
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
207 UnexpectedToken(tokenValue, tokenType);
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
208 m_context = m_stack.Pop();
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
209
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
210 m_elementValue = null;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
211 m_elementType = JSONElementType.EndArray;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
212 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
213 case JsonTokenType.String:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
214 if (m_memberContext == MemberContext.MemberName) {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
215 m_memberName = (string)tokenValue;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
216 break;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
217 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
218 m_elementType = JSONElementType.Value;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
219 m_elementValue = tokenValue;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
220 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
221 case JsonTokenType.Number:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
222 m_elementType = JSONElementType.Value;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
223 m_elementValue = tokenValue;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
224 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
225 case JsonTokenType.Literal:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
226 m_elementType = JSONElementType.Value;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
227 m_elementValue = ParseLiteral((string)tokenValue);
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
228 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
229 case JsonTokenType.NameSeparator:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
230 m_memberContext = MemberContext.MemberValue;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
231 break;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
232 case JsonTokenType.ValueSeparator:
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
233 m_memberContext = m_context.ElementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
234 break;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
235 default:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
236 UnexpectedToken(tokenValue, tokenType);
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
237 break;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
238 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
239 }
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
240 if (m_context.ElementContext != JSONElementContext.None)
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
241 throw new ParserException("Unexpedted end of data");
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
242
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
243 EOF = true;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
244
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
245 return false;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
246 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
247
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
248 object ParseLiteral(string literal) {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
249 switch (literal) {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
250 case "null":
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
251 return null;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
252 case "false":
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
253 return false;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
254 case "true":
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
255 return true;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
256 default:
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
257 UnexpectedToken(literal, JsonTokenType.Literal);
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
258 return null; // avoid compliler error
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
259 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
260 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
261
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
262 void UnexpectedToken(object value, JsonTokenType tokenType) {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
263 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
264 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
265
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
266
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
267 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
268 /// Признак конца потока
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
269 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
270 public bool EOF {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
271 get;
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
272 private set;
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
273 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
274
165
e227e78d72e4 DFA refactoring
cin
parents: 163
diff changeset
275 protected override void Dispose(bool disposing) {
180
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
276 if (disposing)
c32688129f14 refactoring complete, JSONParser rewritten
cin
parents: 178
diff changeset
277 Safe.Dispose(m_scanner);
163
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
278 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
279
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
280 /// <summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
281 /// Переходит в конец текущего объекта.
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
282 /// </summary>
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
283 public void SeekElementEnd() {
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
284 var level = Level - 1;
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
285
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
286 Debug.Assert(level >= 0);
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
287
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
288 while (Level != level)
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
289 Read();
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
290 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
291 }
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
292
419aa51b04fd JSON moved to Formats namespace
cin
parents:
diff changeset
293 }