##// END OF EJS Templates
fixes
cin -
r140:f973c5df9972 v2
parent child
Show More
@@ -1,41 +1,41
1 1 namespace Implab.Diagnostics {
2 2 public static class Extensions {
3 3 public static IPromise<T> EndLogicalOperation<T>(this IPromise<T> promise) {
4 4 Safe.ArgumentNotNull(promise, "promise");
5 5 var op = TraceContext.Instance.DetachLogicalOperation();
6 6
7 7 return promise.On(
8 8 x => {
9 9 TraceContext.Instance.EnterLogicalOperation(op,true);
10 10 TraceLog.TraceInformation("promise = {0}", x);
11 11 TraceLog.EndLogicalOperation();
12 12 TraceContext.Instance.Leave();
13 13 },
14 14 err =>{
15 15 TraceContext.Instance.EnterLogicalOperation(op,true);
16 16 TraceLog.TraceError("promise died {0}", err);
17 17 TraceLog.EndLogicalOperation();
18 18 TraceContext.Instance.Leave();
19 19 },
20 20 reason => {
21 21 TraceContext.Instance.EnterLogicalOperation(op,true);
22 TraceLog.TraceInformation("promise cancelled {0}", reason.Message);
22 TraceLog.TraceInformation("promise cancelled {0}", reason == null ? "<no-reason>" : reason.Message);
23 23 TraceLog.EndLogicalOperation();
24 24 TraceContext.Instance.Leave();
25 25 }
26 26 );
27 27 }
28 28
29 29 public static IPromise EndLogicalOperation(this IPromise promise) {
30 30 Safe.ArgumentNotNull(promise, "promise");
31 31 var op = TraceContext.Instance.DetachLogicalOperation();
32 32
33 33 return promise.On(() => {
34 34 TraceContext.Instance.EnterLogicalOperation(op,true);
35 35 TraceLog.EndLogicalOperation();
36 36 TraceContext.Instance.Leave();
37 37 }, PromiseEventType.All);
38 38 }
39 39 }
40 40 }
41 41
@@ -1,280 +1,283
1 1 using Implab;
2 2 using Implab.Parsing;
3 3 using System;
4 4 using System.Collections.Generic;
5 5 using System.Diagnostics;
6 6 using System.IO;
7 7 using System.Linq;
8 8 using System.Text;
9 9 using System.Threading.Tasks;
10 10
11 11 namespace Implab.JSON {
12 12 /// <summary>
13 13 /// internal
14 14 /// </summary>
15 15 public struct JSONParserContext {
16 16 public string memberName;
17 17 public JSONElementContext elementContext;
18 18 }
19 19
20 20 /// <summary>
21 21 /// Pull парсер JSON данных.
22 22 /// </summary>
23 23 /// <remarks>
24 24 /// Следует отметить отдельную интерпретацию свойства <see cref="Level"/>,
25 25 /// оно означает текущий уровень вложенности объектов, однако закрывающий
26 26 /// элемент объекта и массива имеет уровень меньше, чем сам объект.
27 27 /// <code>
28 28 /// { // Level = 1
29 29 /// "name" : "Peter", // Level = 1
30 30 /// "address" : { // Level = 2
31 31 /// city : "Stern" // Level = 2
32 32 /// } // Level = 1
33 33 /// } // Level = 0
34 34 /// </code>
35 35 /// </remarks>
36 36 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
37 37
38 38 enum MemberContext {
39 39 MemberName,
40 40 MemberValue
41 41 }
42 42
43 43 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
44 44 static readonly DFAStateDescriptior[] _jsonDFA;
45 45 static readonly DFAStateDescriptior[] _objectDFA;
46 46 static readonly DFAStateDescriptior[] _arrayDFA;
47 47
48 48 static JSONParser() {
49 var jsonExpression = Token.New(JsonTokenType.BeginObject, JsonTokenType.BeginArray).Tag(0);
49
50 50
51 51 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
52 52 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
53
53 54 var objectExpression = memberExpression
54 55 .Cat(
55 56 Token.New(JsonTokenType.ValueSeparator)
56 57 .Cat(memberExpression)
57 58 .EClosure()
58 59 )
59 60 .Optional()
60 61 .Cat(Token.New(JsonTokenType.EndObject))
61 62 .Tag(0);
62 63 var arrayExpression = valueExpression
63 64 .Cat(
64 65 Token.New(JsonTokenType.ValueSeparator)
65 66 .Cat(valueExpression)
66 67 .EClosure()
67 68 )
68 69 .Optional()
69 70 .Cat(Token.New(JsonTokenType.EndArray))
70 71 .Tag(0);
71 72
73 var jsonExpression = valueExpression.Tag(0);
74
72 75 _jsonDFA = BuildDFA(jsonExpression).States;
73 76 _objectDFA = BuildDFA(objectExpression).States;
74 77 _arrayDFA = BuildDFA(arrayExpression).States;
75 78 }
76 79
77 80 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
78 81 var builder = new DFABuilder();
79 82 var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
80 83 expr.Accept(builder);
81 84
82 85 builder.BuildDFA(dfa);
83 86 return dfa;
84 87 }
85 88
86 89 JSONScanner m_scanner;
87 90 MemberContext m_memberContext;
88 91
89 92 JSONElementType m_elementType;
90 93 object m_elementValue;
91 94
92 95 /// <summary>
93 96 /// Создает новый парсер на основе строки, содержащей JSON
94 97 /// </summary>
95 98 /// <param name="text"></param>
96 99 public JSONParser(string text)
97 100 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
98 101 Safe.ArgumentNotEmpty(text, "text");
99 102 m_scanner = new JSONScanner();
100 103 m_scanner.Feed(text.ToCharArray());
101 104 }
102 105
103 106 /// <summary>
104 107 /// Создает новый экземпляр парсера, на основе текстового потока.
105 108 /// </summary>
106 109 /// <param name="reader">Текстовый поток.</param>
107 110 /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param>
108 111 public JSONParser(TextReader reader, bool dispose)
109 112 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
110 113 Safe.ArgumentNotNull(reader, "reader");
111 114 m_scanner = new JSONScanner();
112 115 m_scanner.Feed(reader, dispose);
113 116 }
114 117
115 118 /// <summary>
116 119 /// Тип текущего элемента на котором стоит парсер.
117 120 /// </summary>
118 121 public JSONElementType ElementType {
119 122 get { return m_elementType; }
120 123 }
121 124
122 125 /// <summary>
123 126 /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
124 127 /// пустая строка.
125 128 /// </summary>
126 129 public string ElementName {
127 130 get { return m_context.info.memberName; }
128 131 }
129 132
130 133 /// <summary>
131 134 /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c>
132 135 /// </summary>
133 136 public object ElementValue {
134 137 get { return m_elementValue; }
135 138 }
136 139
137 140 /// <summary>
138 141 /// Читает слеюудущий объект из потока
139 142 /// </summary>
140 143 /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns>
141 144 public bool Read() {
142 145 if (m_context.current == UNREACHEBLE_STATE)
143 146 throw new InvalidOperationException("The parser is in invalid state");
144 147 object tokenValue;
145 148 JsonTokenType tokenType;
146 149 m_context.info.memberName = String.Empty;
147 150 while (m_scanner.ReadToken(out tokenValue, out tokenType)) {
148 151 Move((int)tokenType);
149 152 if (m_context.current == UNREACHEBLE_STATE)
150 153 UnexpectedToken(tokenValue, tokenType);
151 154 switch (tokenType) {
152 155 case JsonTokenType.BeginObject:
153 156 Switch(
154 157 _objectDFA,
155 158 INITIAL_STATE,
156 159 new JSONParserContext {
157 160 memberName = m_context.info.memberName,
158 161 elementContext = JSONElementContext.Object
159 162 }
160 163 );
161 164 m_elementValue = null;
162 165 m_memberContext = MemberContext.MemberName;
163 166 m_elementType = JSONElementType.BeginObject;
164 167 return true;
165 168 case JsonTokenType.EndObject:
166 169 Restore();
167 170 m_elementValue = null;
168 171 m_elementType = JSONElementType.EndObject;
169 172 return true;
170 173 case JsonTokenType.BeginArray:
171 174 Switch(
172 175 _arrayDFA,
173 176 INITIAL_STATE,
174 177 new JSONParserContext {
175 178 memberName = m_context.info.memberName,
176 179 elementContext = JSONElementContext.Array
177 180 }
178 181 );
179 182 m_elementValue = null;
180 183 m_memberContext = MemberContext.MemberValue;
181 184 m_elementType = JSONElementType.BeginArray;
182 185 return true;
183 186 case JsonTokenType.EndArray:
184 187 Restore();
185 188 m_elementValue = null;
186 189 m_elementType = JSONElementType.EndArray;
187 190 return true;
188 191 case JsonTokenType.String:
189 192 if (m_memberContext == MemberContext.MemberName) {
190 193 m_context.info.memberName = (string)tokenValue;
191 194 break;
192 195 } else {
193 196 m_elementType = JSONElementType.Value;
194 197 m_elementValue = tokenValue;
195 198 return true;
196 199 }
197 200 case JsonTokenType.Number:
198 201 m_elementType = JSONElementType.Value;
199 202 m_elementValue = tokenValue;
200 203 return true;
201 204 case JsonTokenType.Literal:
202 205 m_elementType = JSONElementType.Value;
203 206 m_elementValue = ParseLiteral((string)tokenValue);
204 207 return true;
205 208 case JsonTokenType.NameSeparator:
206 209 m_memberContext = MemberContext.MemberValue;
207 210 break;
208 211 case JsonTokenType.ValueSeparator:
209 212 m_memberContext = m_context.info.elementContext == JSONElementContext.Object ? MemberContext.MemberName : MemberContext.MemberValue;
210 213 break;
211 214 default:
212 215 UnexpectedToken(tokenValue, tokenType);
213 216 break;
214 217 }
215 218 }
216 219 if (m_context.info.elementContext != JSONElementContext.None)
217 220 throw new ParserException("Unexpedted end of data");
218 221 return false;
219 222 }
220 223
221 224 object ParseLiteral(string literal) {
222 225 switch (literal) {
223 226 case "null":
224 227 return null;
225 228 case "false":
226 229 return false;
227 230 case "true":
228 231 return true;
229 232 default:
230 233 UnexpectedToken(literal, JsonTokenType.Literal);
231 234 return null; // avoid compliler error
232 235 }
233 236 }
234 237
235 238 void UnexpectedToken(object value, JsonTokenType tokenType) {
236 239 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
237 240 }
238 241
239 242
240 243 /// <summary>
241 244 /// Признак конца потока
242 245 /// </summary>
243 246 public bool EOF {
244 247 get {
245 248 return m_scanner.EOF;
246 249 }
247 250 }
248 251
249 252 protected virtual void Dispose(bool disposing) {
250 253 if (disposing) {
251 254 m_scanner.Dispose();
252 255 }
253 256 }
254 257
255 258 /// <summary>
256 259 /// Освобождает парсер и связанный с ним сканнер.
257 260 /// </summary>
258 261 public void Dispose() {
259 262 Dispose(true);
260 263 GC.SuppressFinalize(this);
261 264 }
262 265
263 266 ~JSONParser() {
264 267 Dispose(false);
265 268 }
266 269
267 270 /// <summary>
268 271 /// Переходит в конец текущего объекта.
269 272 /// </summary>
270 273 public void SeekElementEnd() {
271 274 var level = Level - 1;
272 275
273 276 Debug.Assert(level >= 0);
274 277
275 278 while (Level != level)
276 279 Read();
277 280 }
278 281 }
279 282
280 283 }
General Comments 0
You need to be logged in to leave comments. Login now