Mercurial > pub > ImplabNet
comparison Implab/Formats/JSON/JSONParser.cs @ 178:d5c5db0335ee ref20160224
working on JSON parser
author | cin |
---|---|
date | Wed, 23 Mar 2016 19:51:45 +0300 |
parents | 92d5278d1b10 |
children | c32688129f14 |
comparison
equal
deleted
inserted
replaced
177:a0ff6a0e9c44 | 178:d5c5db0335ee |
---|---|
36 enum MemberContext { | 36 enum MemberContext { |
37 MemberName, | 37 MemberName, |
38 MemberValue | 38 MemberValue |
39 } | 39 } |
40 | 40 |
41 #region Parser rules | |
41 struct ParserContext { | 42 struct ParserContext { |
42 DFAStateDescriptior<object> | 43 readonly int[,] m_dfa; |
43 } | 44 int m_state; |
44 | 45 |
45 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; | 46 readonly JSONElementContext m_elementContext; |
46 static readonly DFAStateDescriptior<object>[] _jsonDFA; | 47 |
47 static readonly int _jsonDFAInitialState; | 48 public ParserContext(int[,] dfa, int state, JSONElementContext context) { |
48 static readonly DFAStateDescriptior<object>[] _objectDFA; | 49 m_dfa = dfa; |
49 static readonly int _objectDFAInitialState; | 50 m_state = state; |
50 static readonly DFAStateDescriptior<object>[] _arrayDFA; | 51 m_elementContext = context; |
51 static readonly int _arrayDFAInitialState; | 52 } |
53 | |
54 public bool Move(JsonTokenType token) { | |
55 var next = m_dfa[m_state, token]; | |
56 if (next == AutomatonConst.UNREACHABLE_STATE) | |
57 return false; | |
58 m_state = next; | |
59 } | |
60 | |
61 public JSONElementContext ElementContext { | |
62 get { return m_elementContext; } | |
63 } | |
64 } | |
52 | 65 |
53 static JSONParser() { | 66 static JSONParser() { |
54 | 67 |
55 | 68 |
56 var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); | 69 var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String); |
62 .Cat(memberExpression) | 75 .Cat(memberExpression) |
63 .EClosure() | 76 .EClosure() |
64 ) | 77 ) |
65 .Optional() | 78 .Optional() |
66 .Cat(Token(JsonTokenType.EndObject)) | 79 .Cat(Token(JsonTokenType.EndObject)) |
67 .Tag(null); | 80 .End(); |
81 | |
68 var arrayExpression = valueExpression | 82 var arrayExpression = valueExpression |
69 .Cat( | 83 .Cat( |
70 Token(JsonTokenType.ValueSeparator) | 84 Token(JsonTokenType.ValueSeparator) |
71 .Cat(valueExpression) | 85 .Cat(valueExpression) |
72 .EClosure() | 86 .EClosure() |
73 ) | 87 ) |
74 .Optional() | 88 .Optional() |
75 .Cat(Token(JsonTokenType.EndArray)) | 89 .Cat(Token(JsonTokenType.EndArray)) |
76 .Tag(null); | 90 .End(); |
77 | 91 |
78 var jsonExpression = valueExpression.Tag(null); | 92 var jsonExpression = valueExpression.End(); |
79 | 93 |
80 _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable(); | 94 _jsonDFA = CreateParserContext(jsonExpression, JSONElementContext.None); |
81 _objectDFA = CreateDFA(objectExpression).GetTransitionTable(); | 95 _objectDFA = CreateParserContext(objectExpression, JSONElementContext.Object); |
82 _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable(); | 96 _arrayDFA = CreateParserContext(arrayExpression, JSONElementContext.Array); |
83 } | 97 } |
84 | 98 |
85 static Token<object> Token(params JsonTokenType[] input) { | 99 static Token Token(params JsonTokenType[] input) { |
86 return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray()); | 100 return Token.New( input.Select(t => (int)t).ToArray() ); |
87 } | 101 } |
88 | 102 |
89 static RegularDFA<JsonTokenType,object> CreateDFA(Token<object> expr) { | 103 static ParserContext CreateParserContext(Token expr, JSONElementContext context) { |
90 var builder = new RegularExpressionVisitor<object>(); | 104 |
91 var dfa = new RegularDFA<JsonTokenType,object>(_alphabet); | 105 var dfa = new DFATable(); |
92 | 106 var builder = new RegularExpressionVisitor(dfa); |
93 expr.Accept(builder); | 107 expr.Accept(builder); |
94 | 108 builder.BuildDFA(); |
95 builder.BuildDFA(dfa); | 109 |
96 return dfa; | 110 return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context); |
97 } | 111 } |
112 | |
113 #endregion | |
98 | 114 |
99 JSONScanner m_scanner; | 115 JSONScanner m_scanner; |
100 MemberContext m_memberContext; | 116 MemberContext m_memberContext; |
101 | 117 |
102 JSONElementType m_elementType; | 118 JSONElementType m_elementType; |
115 | 131 |
116 /// <summary> | 132 /// <summary> |
117 /// Создает новый экземпляр парсера, на основе текстового потока. | 133 /// Создает новый экземпляр парсера, на основе текстового потока. |
118 /// </summary> | 134 /// </summary> |
119 /// <param name="reader">Текстовый поток.</param> | 135 /// <param name="reader">Текстовый поток.</param> |
120 /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param> | 136 public JSONParser(TextReader reader) |
121 public JSONParser(TextReader reader, bool dispose) | |
122 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) { | 137 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) { |
123 Safe.ArgumentNotNull(reader, "reader"); | 138 Safe.ArgumentNotNull(reader, "reader"); |
124 m_scanner = new JSONScanner(); | 139 m_scanner = new JSONScanner(); |
125 m_scanner.Feed(reader, dispose); | 140 m_scanner.Feed(reader, dispose); |
126 } | 141 } |