Mercurial > pub > ImplabNet
comparison Implab/Formats/JSON/JSONParser.cs @ 165:e227e78d72e4 ref20160224
DFA refactoring
| author | cin |
|---|---|
| date | Mon, 29 Feb 2016 02:02:17 +0300 |
| parents | 419aa51b04fd |
| children | 92d5278d1b10 |
comparison
equal
deleted
inserted
replaced
| 164:ec35731ae299 | 165:e227e78d72e4 |
|---|---|
| 1 using Implab.Parsing; | 1 using System; |
| 2 using System; | |
| 3 using System.Diagnostics; | 2 using System.Diagnostics; |
| 4 using System.IO; | 3 using System.IO; |
| 5 | 4 using Implab.Automaton; |
| 6 namespace Implab.JSON { | 5 using Implab.Automaton.RegularExpressions; |
| 6 using System.Linq; | |
| 7 using Implab.Components; | |
| 8 | |
| 9 namespace Implab.Formats.JSON { | |
| 7 /// <summary> | 10 /// <summary> |
| 8 /// internal | 11 /// internal |
| 9 /// </summary> | 12 /// </summary> |
| 10 public struct JSONParserContext { | 13 public struct JSONParserContext { |
| 11 public string memberName; | 14 public string memberName; |
| 26 /// city : "Stern" // Level = 2 | 29 /// city : "Stern" // Level = 2 |
| 27 /// } // Level = 1 | 30 /// } // Level = 1 |
| 28 /// } // Level = 0 | 31 /// } // Level = 0 |
| 29 /// </code> | 32 /// </code> |
| 30 /// </remarks> | 33 /// </remarks> |
| 31 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable { | 34 public class JSONParser : Disposable { |
| 32 | 35 |
| 33 enum MemberContext { | 36 enum MemberContext { |
| 34 MemberName, | 37 MemberName, |
| 35 MemberValue | 38 MemberValue |
| 36 } | 39 } |
| 37 | 40 |
| 41 struct ParserContext { | |
| 42 DFAStateDescriptior<object> | |
| 43 } | |
| 44 | |
| 38 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; | 45 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; |
| 39 static readonly DFAStateDescriptior[] _jsonDFA; | 46 static readonly DFAStateDescriptior<object>[] _jsonDFA; |
| 40 static readonly DFAStateDescriptior[] _objectDFA; | 47 static readonly int _jsonDFAInitialState; |
| 41 static readonly DFAStateDescriptior[] _arrayDFA; | 48 static readonly DFAStateDescriptior<object>[] _objectDFA; |
| 49 static readonly int _objectDFAInitialState; | |
| 50 static readonly DFAStateDescriptior<object>[] _arrayDFA; | |
| 51 static readonly int _arrayDFAInitialState; | |
| 42 | 52 |
| 43 static JSONParser() { | 53 static JSONParser() { |
| 44 | 54 |
| 45 | 55 |
| 46 var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); | 56 var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); |
| 47 var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression); | 57 var memberExpression = Token(JsonTokenType.String).Cat(Token(JsonTokenType.NameSeparator)).Cat(valueExpression); |
| 48 | 58 |
| 49 var objectExpression = memberExpression | 59 var objectExpression = memberExpression |
| 50 .Cat( | 60 .Cat( |
| 51 Token.New(JsonTokenType.ValueSeparator) | 61 Token(JsonTokenType.ValueSeparator) |
| 52 .Cat(memberExpression) | 62 .Cat(memberExpression) |
| 53 .EClosure() | 63 .EClosure() |
| 54 ) | 64 ) |
| 55 .Optional() | 65 .Optional() |
| 56 .Cat(Token.New(JsonTokenType.EndObject)) | 66 .Cat(Token(JsonTokenType.EndObject)) |
| 57 .Tag(0); | 67 .Tag(null); |
| 58 var arrayExpression = valueExpression | 68 var arrayExpression = valueExpression |
| 59 .Cat( | 69 .Cat( |
| 60 Token.New(JsonTokenType.ValueSeparator) | 70 Token(JsonTokenType.ValueSeparator) |
| 61 .Cat(valueExpression) | 71 .Cat(valueExpression) |
| 62 .EClosure() | 72 .EClosure() |
| 63 ) | 73 ) |
| 64 .Optional() | 74 .Optional() |
| 65 .Cat(Token.New(JsonTokenType.EndArray)) | 75 .Cat(Token(JsonTokenType.EndArray)) |
| 66 .Tag(0); | 76 .Tag(null); |
| 67 | 77 |
| 68 var jsonExpression = valueExpression.Tag(0); | 78 var jsonExpression = valueExpression.Tag(null); |
| 69 | 79 |
| 70 _jsonDFA = BuildDFA(jsonExpression).States; | 80 _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable(); |
| 71 _objectDFA = BuildDFA(objectExpression).States; | 81 _objectDFA = CreateDFA(objectExpression).GetTransitionTable(); |
| 72 _arrayDFA = BuildDFA(arrayExpression).States; | 82 _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable(); |
| 73 } | 83 } |
| 74 | 84 |
| 75 static EDFADefinition<JsonTokenType> BuildDFA(Token expr) { | 85 static Token<object> Token(params JsonTokenType[] input) { |
| 76 var builder = new DFABuilder(); | 86 return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray()); |
| 77 var dfa = new EDFADefinition<JsonTokenType>(_alphabet); | 87 } |
| 88 | |
| 89 static RegularDFADefinition<JsonTokenType,object> CreateDFA(Token<object> expr) { | |
| 90 var builder = new RegularDFABuilder<object>(); | |
| 91 var dfa = new RegularDFADefinition<JsonTokenType,object>(_alphabet); | |
| 92 | |
| 78 expr.Accept(builder); | 93 expr.Accept(builder); |
| 79 | 94 |
| 80 builder.BuildDFA(dfa); | 95 builder.BuildDFA(dfa); |
| 81 return dfa; | 96 return dfa; |
| 82 } | 97 } |
| 241 get { | 256 get { |
| 242 return m_scanner.EOF; | 257 return m_scanner.EOF; |
| 243 } | 258 } |
| 244 } | 259 } |
| 245 | 260 |
| 246 protected virtual void Dispose(bool disposing) { | 261 protected override void Dispose(bool disposing) { |
| 247 if (disposing) { | 262 if (disposing) { |
| 248 m_scanner.Dispose(); | 263 m_scanner.Dispose(); |
| 249 } | 264 } |
| 250 } | 265 } |
| 251 | 266 |
| 252 /// <summary> | 267 /// <summary> |
| 253 /// Освобождает парсер и связанный с ним сканнер. | |
| 254 /// </summary> | |
| 255 public void Dispose() { | |
| 256 Dispose(true); | |
| 257 GC.SuppressFinalize(this); | |
| 258 } | |
| 259 | |
| 260 ~JSONParser() { | |
| 261 Dispose(false); | |
| 262 } | |
| 263 | |
| 264 /// <summary> | |
| 265 /// Переходит в конец текущего объекта. | 268 /// Переходит в конец текущего объекта. |
| 266 /// </summary> | 269 /// </summary> |
| 267 public void SeekElementEnd() { | 270 public void SeekElementEnd() { |
| 268 var level = Level - 1; | 271 var level = Level - 1; |
| 269 | 272 |
