Mercurial > pub > ImplabNet
diff 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 |
line wrap: on
line diff
--- a/Implab/Formats/JSON/JSONParser.cs Wed Mar 23 01:42:00 2016 +0300 +++ b/Implab/Formats/JSON/JSONParser.cs Wed Mar 23 19:51:45 2016 +0300 @@ -38,17 +38,30 @@ MemberValue } + #region Parser rules struct ParserContext { - DFAStateDescriptior<object> - } + readonly int[,] m_dfa; + int m_state; + + readonly JSONElementContext m_elementContext; - static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; - static readonly DFAStateDescriptior<object>[] _jsonDFA; - static readonly int _jsonDFAInitialState; - static readonly DFAStateDescriptior<object>[] _objectDFA; - static readonly int _objectDFAInitialState; - static readonly DFAStateDescriptior<object>[] _arrayDFA; - static readonly int _arrayDFAInitialState; + public ParserContext(int[,] dfa, int state, JSONElementContext context) { + m_dfa = dfa; + m_state = state; + m_elementContext = context; + } + + public bool Move(JsonTokenType token) { + var next = m_dfa[m_state, token]; + if (next == AutomatonConst.UNREACHABLE_STATE) + return false; + m_state = next; + } + + public JSONElementContext ElementContext { + get { return m_elementContext; } + } + } static JSONParser() { @@ -64,7 +77,8 @@ ) .Optional() .Cat(Token(JsonTokenType.EndObject)) - .Tag(null); + .End(); + var arrayExpression = valueExpression .Cat( Token(JsonTokenType.ValueSeparator) @@ -73,29 +87,31 @@ ) .Optional() .Cat(Token(JsonTokenType.EndArray)) - .Tag(null); + .End(); - var jsonExpression = valueExpression.Tag(null); + var jsonExpression = valueExpression.End(); - _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable(); - _objectDFA = CreateDFA(objectExpression).GetTransitionTable(); - _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable(); + _jsonDFA = CreateParserContext(jsonExpression, JSONElementContext.None); + _objectDFA = CreateParserContext(objectExpression, JSONElementContext.Object); + _arrayDFA = CreateParserContext(arrayExpression, JSONElementContext.Array); } - static Token<object> Token(params JsonTokenType[] input) { - return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray()); + static Token Token(params JsonTokenType[] input) { + return Token.New( input.Select(t => (int)t).ToArray() ); } - static RegularDFA<JsonTokenType,object> CreateDFA(Token<object> expr) { - var builder = new RegularExpressionVisitor<object>(); - var dfa = new RegularDFA<JsonTokenType,object>(_alphabet); - + static ParserContext CreateParserContext(Token expr, JSONElementContext context) { + + var dfa = new DFATable(); + var builder = new RegularExpressionVisitor(dfa); expr.Accept(builder); + builder.BuildDFA(); - builder.BuildDFA(dfa); - return dfa; + return new ParserContext(dfa.CreateTransitionTable(), dfa.InitialState, context); } + #endregion + JSONScanner m_scanner; MemberContext m_memberContext; @@ -117,8 +133,7 @@ /// Создает новый экземпляр парсера, на основе текстового потока. /// </summary> /// <param name="reader">Текстовый поток.</param> - /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param> - public JSONParser(TextReader reader, bool dispose) + public JSONParser(TextReader reader) : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) { Safe.ArgumentNotNull(reader, "reader"); m_scanner = new JSONScanner();