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();