changeset 165:e227e78d72e4 ref20160224

DFA refactoring
author cin
date Mon, 29 Feb 2016 02:02:17 +0300
parents ec35731ae299
children b84cdbe82e7f
files Implab/Automaton/DFAStateDescriptor.cs Implab/Automaton/DFATransitionTable.cs Implab/Automaton/DFAutomaton.cs Implab/Automaton/IDFATable.cs Implab/Automaton/IDFATableBuilder.cs Implab/Automaton/IDFATransitionTable.cs Implab/Automaton/IDFATransitionTableBuilder.cs Implab/Automaton/RegularExpressions/Grammar.cs Implab/Automaton/RegularExpressions/RegularDFABuilder.cs Implab/Automaton/RegularExpressions/RegularDFADefinition.cs Implab/Automaton/RegularExpressions/Token.cs Implab/Automaton/Scanner.cs Implab/Formats/ByteAlphabet.cs Implab/Formats/CharAlphabet.cs Implab/Formats/JSON/JSONElementContext.cs Implab/Formats/JSON/JSONElementType.cs Implab/Formats/JSON/JSONGrammar.cs Implab/Formats/JSON/JSONParser.cs Implab/Formats/JSON/JSONScanner.cs Implab/Formats/JSON/JsonTokenType.cs Implab/Formats/RegularCharDFADefinition.cs Implab/Implab.csproj
diffstat 22 files changed, 246 insertions(+), 296 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/Automaton/DFAStateDescriptor.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/DFAStateDescriptor.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,7 +1,15 @@
 namespace Implab.Automaton {
-    public struct DFAStateDescriptior<TTag> {
-        public bool final;
-        public TTag[] tag;
-        public int[] transitions;
+    public struct DFAStateDescriptior {
+        public readonly bool final;
+        public readonly int[] transitions;
+
+
+        public DFAStateDescriptior(int[] transitions, bool final) {
+            this.transitions = transitions;
+            this.final = final;
+        }
+
+        public DFAStateDescriptior(int[] transitions) : this(transitions, false) {
+        }
     }
 }
--- a/Implab/Automaton/DFATransitionTable.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/DFATransitionTable.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -4,8 +4,8 @@
 using System.Linq;
 
 namespace Implab.Automaton {
-    public class DFATransitionTable<TTag> : IDFATransitionTableBuilder<TTag> {
-        DFAStateDescriptior<TTag>[] m_dfaTable;
+    public class DFATransitionTable<TTag> : IDFATableBuilder {
+        DFAStateDescriptior[] m_dfaTable;
 
         int m_stateCount;
         int m_symbolCount;
@@ -17,7 +17,7 @@
 
         #region IDFADefinition implementation
 
-        public DFAStateDescriptior<TTag>[] GetTransitionTable() {
+        public DFAStateDescriptior[] GetTransitionTable() {
             if (m_dfaTable == null) {
                 if (m_stateCount <= 0)
                     throw new InvalidOperationException("Invalid automaton definition: states count = {0}", m_stateCount);
@@ -108,7 +108,7 @@
         #endregion
 
         protected void Optimize<TInput, TState>(
-            IDFATransitionTableBuilder<TTag> optimalDFA,
+            IDFATableBuilder<TTag> optimalDFA,
             IAlphabet<TInput> inputAlphabet,
             IAlphabetBuilder<TInput> optimalInputAlphabet,
             IAlphabet<TState> stateAlphabet,
--- a/Implab/Automaton/DFAutomaton.cs	Thu Feb 25 02:11:13 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-using Implab;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.Automaton {
-    public abstract class DFAutomaton<T> {
-        protected struct ContextFrame {
-            public DFAStateDescriptior[] states;
-            public int current;
-            public T info;
-        }
-
-        public const int INITIAL_STATE = DFADefinition.INITIAL_STATE;
-        public const int UNREACHEBLE_STATE = DFADefinition.UNREACHEBLE_STATE;
-
-        protected ContextFrame m_context;
-        Stack<ContextFrame> m_contextStack = new Stack<ContextFrame>();
-
-        protected int Level {
-            get { return m_contextStack.Count; }
-        }
-
-        protected DFAutomaton(DFAStateDescriptior[] states, int startState, T info) {
-            Safe.ArgumentNotNull(states, "states");
-            Safe.ArgumentInRange(startState, 0, states.Length - 1, "startState");
- 
-            m_context.states = states;
-            m_context.current = startState;
-            m_context.info = info;
-        }
-
-        protected void Switch(DFAStateDescriptior[] states, int current, T info) {
-            Debug.Assert(states != null);
-            Debug.Assert(current >= 0 && current < states.Length);
-            m_contextStack.Push(m_context);
-            m_context.states = states;
-            m_context.current = current;
-            m_context.info = info;
-        }
-
-        protected void Restore() {
-            Debug.Assert(m_contextStack.Count > 0);
-
-            m_context = m_contextStack.Pop();
-        }
-
-        protected void Move(int input) {
-            Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
-            m_context.current = m_context.states[m_context.current].transitions[input];
-        }
-
-        protected bool CanMove(int input) {
-            Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length);
-            return m_context.states[m_context.current].transitions[input] != UNREACHEBLE_STATE;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Automaton/IDFATable.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -0,0 +1,59 @@
+using System.Collections.Generic;
+
+
+namespace Implab.Automaton {
+    /// <summary>
+    /// Полностью описывает DFA автомат, его поведение, состояние и входные символы.
+    /// </summary>
+    /// <example>
+    /// class MyAutomaton {
+    ///     int m_current;
+    ///     readonly DFAStateDescriptor<string>[] m_automaton;
+    ///     readonly IAlphabet<MyCommands> m_commands;
+    /// 
+    ///     public MyAutomaton(IDFADefinition&lt;MyCommands,MyStates,string&gt; definition) {
+    ///         m_current = definition.StateAlphabet.Translate(MyStates.Initial);
+    ///         m_automaton = definition.GetTransitionTable();
+    ///         m_commands = definition.InputAlphabet;
+    ///     }
+    /// 
+    ///     // defined a method which will move the automaton to the next state
+    ///     public void Move(MyCommands cmd) {
+    ///         // use transition map to determine the next state
+    ///         var next = m_automaton[m_current].transitions[m_commands.Translate(cmd)];
+    /// 
+    ///         // validate that we aren't in the unreachable state
+    ///         if (next == DFAConst.UNREACHABLE_STATE)
+    ///             throw new InvalidOperationException("The specified command is invalid");
+    /// 
+    ///         // if everything is ok
+    ///         m_current = next;
+    ///     }
+    /// }
+    /// </example>
+    public interface IDFATable {
+        /// <summary>
+        /// Таблица переходов состояний автомата
+        /// </summary>
+        /// <returns>The transition table.</returns>
+        DFAStateDescriptior[] GetTransitionTable();
+
+        int StateCount {
+            get;
+        }
+
+        int AlphabetSize {
+            get;
+        }
+
+        int InitialState {
+            get;
+        }
+
+        bool IsFinalState(int s);
+
+        IEnumerable<int> FinalStates {
+            get;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Automaton/IDFATableBuilder.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -0,0 +1,24 @@
+using System;
+
+namespace Implab.Automaton {
+    public interface IDFATableBuilder : IDFATable {
+        /// <summary>
+        /// Marks the state as final.
+        /// </summary>
+        /// <param name="state">State.</param>
+        void MarkFinalState(int state);
+
+        /// <summary>
+        /// Defines the transition from <paramref name="s1"/> to
+        /// <paramref name="s2"/> with input <paramref name="symbol"/>.
+        /// </summary>
+        /// <param name="s1">S1.</param>
+        /// <param name="s2">S2.</param>
+        /// <param name="symbol">Symbol.</param>
+        void DefineTransition(int s1, int s2, int symbol);
+
+        void SetInitialState(int s);
+
+    }
+}
+
--- a/Implab/Automaton/IDFATransitionTable.cs	Thu Feb 25 02:11:13 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-using System.Collections.Generic;
-
-
-namespace Implab.Automaton {
-    /// <summary>
-    /// Полностью описывает DFA автомат, его поведение, состояние и входные символы.
-    /// </summary>
-    /// <example>
-    /// class MyAutomaton {
-    ///     int m_current;
-    ///     readonly DFAStateDescriptor<string>[] m_automaton;
-    ///     readonly IAlphabet<MyCommands> m_commands;
-    /// 
-    ///     public MyAutomaton(IDFADefinition&lt;MyCommands,MyStates,string&gt; definition) {
-    ///         m_current = definition.StateAlphabet.Translate(MyStates.Initial);
-    ///         m_automaton = definition.GetTransitionTable();
-    ///         m_commands = definition.InputAlphabet;
-    ///     }
-    /// 
-    ///     // defined a method which will move the automaton to the next state
-    ///     public void Move(MyCommands cmd) {
-    ///         // use transition map to determine the next state
-    ///         var next = m_automaton[m_current].transitions[m_commands.Translate(cmd)];
-    /// 
-    ///         // validate that we aren't in the unreachable state
-    ///         if (next == DFAConst.UNREACHABLE_STATE)
-    ///             throw new InvalidOperationException("The specified command is invalid");
-    /// 
-    ///         // if everything is ok
-    ///         m_current = next;
-    ///     }
-    /// }
-    /// </example>
-    public interface IDFATransitionTable<TTag> {
-        /// <summary>
-        /// Таблица переходов состояний автомата
-        /// </summary>
-        /// <returns>The transition table.</returns>
-        DFAStateDescriptior<TTag>[] GetTransitionTable();
-
-        int StateCount {
-            get;
-        }
-
-        int AlphabetSize {
-            get;
-        }
-
-        int InitialState {
-            get;
-        }
-
-        bool IsFinalState(int s);
-
-        IEnumerable<KeyValuePair<int,TTag[]>> FinalStates {
-            get;
-        }
-    }
-}
--- a/Implab/Automaton/IDFATransitionTableBuilder.cs	Thu Feb 25 02:11:13 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-using System;
-
-namespace Implab.Automaton {
-    public interface IDFATransitionTableBuilder<TTag> : IDFATransitionTable<TTag> {
-        /// <summary>
-        /// Marks the state as final and assings tags.
-        /// </summary>
-        /// <param name="state">State.</param>
-        /// <param name="tags">Tags.</param>
-        void MarkFinalState(int state, params TTag[] tags);
-
-        /// <summary>
-        /// Defines the transition from <paramref name="s1"/> to
-        /// <paramref name="s2"/> with input <paramref name="symbol"/>.
-        /// </summary>
-        /// <param name="s1">S1.</param>
-        /// <param name="s2">S2.</param>
-        /// <param name="symbol">Symbol.</param>
-        void DefineTransition(int s1, int s2, int symbol);
-
-        void SetInitialState(int s);
-
-    }
-}
-
--- a/Implab/Automaton/RegularExpressions/Grammar.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/RegularExpressions/Grammar.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -2,48 +2,46 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Implab.Automaton.RegularExpressions {
     /// <summary>
     /// Базовый абстрактный класс. Грамматика, позволяет формулировать выражения над алфавитом типа <c>char</c>.
     /// </summary>
-        public abstract class Grammar<TSymbol, TTag> {
+    public abstract class Grammar<TSymbol, TTag> {
         
-        public abstract IAlphabetBuilder<TSymbol> Alphabet {
+        protected abstract IAlphabetBuilder<TSymbol> AlphabetBuilder {
             get;
         }
 
-        public SymbolToken<TTag> UnclassifiedToken() {
+        protected SymbolToken<TTag> UnclassifiedToken() {
             return new SymbolToken<TTag>(DFAConst.UNCLASSIFIED_INPUT);
         }
 
-        public void DefineAlphabet(IEnumerable<TSymbol> alphabet) {
+        protected void DefineAlphabet(IEnumerable<TSymbol> alphabet) {
             Safe.ArgumentNotNull(alphabet, "alphabet");
 
             foreach (var ch in alphabet)
-                Alphabet.DefineSymbol(ch);
+                AlphabetBuilder.DefineSymbol(ch);
         }
 
-        public Token<TTag> SymbolToken(TSymbol symbol) {
+        protected Token<TTag> SymbolToken(TSymbol symbol) {
             return Token<TTag>.New(TranslateOrAdd(symbol));
         }
 
-        public Token<TTag> SymbolToken(IEnumerable<TSymbol> symbols) {
+        protected Token<TTag> SymbolToken(IEnumerable<TSymbol> symbols) {
             Safe.ArgumentNotNull(symbols, "symbols");
 
             return Token<TTag>.New(TranslateOrAdd(symbols).ToArray());
         }
 
-        public Token<TTag> SymbolSetToken(params TSymbol[] set) {
+        protected Token<TTag> SymbolSetToken(params TSymbol[] set) {
             return SymbolToken(set);
         }
 
         int TranslateOrAdd(TSymbol ch) {
-            var t = Alphabet.Translate(ch);
+            var t = AlphabetBuilder.Translate(ch);
             if (t == DFAConst.UNCLASSIFIED_INPUT)
-                t = Alphabet.DefineSymbol(ch);
+                t = AlphabetBuilder.DefineSymbol(ch);
             return t;
         }
 
@@ -52,7 +50,7 @@
         }
 
         int TranslateOrDie(TSymbol ch) {
-            var t = Alphabet.Translate(ch);
+            var t = AlphabetBuilder.Translate(ch);
             if (t == DFAConst.UNCLASSIFIED_INPUT)
                     throw new ApplicationException(String.Format("Symbol '{0}' is UNCLASSIFIED", ch));
             return t;
@@ -62,33 +60,31 @@
             return symbols.Distinct().Select(TranslateOrDie);
         }
 
-        public Token<TTag> SymbolTokenExcept(IEnumerable<TSymbol> symbols) {
+        protected Token<TTag> SymbolTokenExcept(IEnumerable<TSymbol> symbols) {
             Safe.ArgumentNotNull(symbols, "symbols");
 
-            return Token<TTag>.New( Enumerable.Range(0, Alphabet.Count).Except(TranslateOrDie(symbols)).ToArray() );
+            return Token<TTag>.New( Enumerable.Range(0, AlphabetBuilder.Count).Except(TranslateOrDie(symbols)).ToArray() );
         }
 
-        protected CDFADefinition BuildDFA(Token<TTag> lang) {
+        protected void BuildDFA(Token<TTag> lang, IDFATableBuilder<TTag> dfaTable, IAlphabetBuilder<TSymbol> dfaAlphabet) {
             Safe.ArgumentNotNull(lang, "lang");
+            Safe.ArgumentNotNull(dfaAlphabet, "dfaAlphabet");
 
-            var dfa = new RegularDFADefinition<TSymbol, TTag>(Alphabet, 0);
-
-            var table = new DFATransitionTable<TTag>();
+            var dfa = new RegularDFADefinition<TSymbol, TTag>(AlphabetBuilder);
 
             var builder = new RegularDFABuilder<TTag>();
 
             lang.Accept( builder );
 
-            var initialState = builder.BuildDFA(table);
-            if (table.IsFinalState(initialState))
+            builder.BuildDFA(dfa);
+
+            if (dfa.IsFinalState(dfa.InitialState))
                 throw new ApplicationException("The specified language contains empty token");
 
-            return dfa.Optimize();
+            dfa.Optimize(dfaTable, dfaAlphabet);
+
         }
 
-        
-
-        //protected abstract TGrammar CreateInstance();
     }
 
 
--- a/Implab/Automaton/RegularExpressions/RegularDFABuilder.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/RegularExpressions/RegularDFABuilder.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -11,7 +11,7 @@
     /// <see cref="BuildDFA(IDFADefinition)"/> для построения автомата.
     /// </summary>
     public class RegularDFABuilder<TTag> : IVisitor<TTag> {
-        int m_idx = 0;
+        int m_idx;
         Token<TTag> m_root;
         HashSet<int> m_firstpos;
         HashSet<int> m_lastpos;
@@ -26,18 +26,18 @@
 
         public HashSet<int> Followpos(int pos) {
             HashSet<int> set;
-            if (m_followpos.TryGetValue(pos, out set))
-                return set;
-            return m_followpos[pos] = new HashSet<int>();
+            return m_followpos.TryGetValue(pos, out set) ? set : m_followpos[pos] = new HashSet<int>();
         }
 
         bool Nullable(object n) {
             if (n is EmptyToken<TTag> || n is StarToken<TTag>)
                 return true;
-            if (n is AltToken<TTag>)
-                return Nullable(((AltToken<TTag>)n).Left) || Nullable(((AltToken<TTag>)n).Right);
-            if (n is CatToken<TTag>)
-                return Nullable(((CatToken<TTag>)n).Left) && Nullable(((CatToken<TTag>)n).Right);
+            var altToken = n as AltToken<TTag>;
+            if (altToken != null)
+                return Nullable(altToken.Left) || Nullable(altToken.Right);
+            var catToken = n as CatToken<TTag>;
+            if (catToken != null)
+                return Nullable(catToken.Left) && Nullable(catToken.Right);
             return false;
         }
 
@@ -122,7 +122,7 @@
             m_ends.Add(m_idx, token.Tag);
         }
 
-        public void BuildDFA(IDFATransitionTableBuilder<TTag> dfa) {
+        public void BuildDFA(IDFATableBuilder<TTag> dfa) {
             Safe.ArgumentNotNull(dfa,"dfa");
 
             var states = new MapAlphabet<HashSet<int>>(new CustomEqualityComparer<HashSet<int>>(
--- a/Implab/Automaton/RegularExpressions/RegularDFADefinition.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/RegularExpressions/RegularDFADefinition.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -4,13 +4,11 @@
     public class RegularDFADefinition<TInput, TTag> : DFATransitionTable<TTag>, IDFATransitionTable<TTag> {
 
         readonly IAlphabet<TInput> m_alphabet;
-        readonly int m_initialState;
 
-        public RegularDFADefinition(IAlphabet<TInput> alphabet, int initialState) {
+        public RegularDFADefinition(IAlphabet<TInput> alphabet) {
             Safe.ArgumentNotNull(alphabet, "aplhabet");
 
             m_alphabet = alphabet;
-            m_initialState = initialState;
         }
 
 
@@ -30,14 +28,13 @@
         /// <summary>
         /// Optimize the specified alphabet.
         /// </summary>
+        /// <param name = "dfaTable"></param>
         /// <param name="alphabet">Пустой алфавит, который будет зполнен в процессе оптимизации.</param>
-        public  RegularDFADefinition<TInput, TTag> Optimize(IAlphabetBuilder<TInput> alphabet) {
+        public void Optimize(IDFATableBuilder<TTag> dfaTable, IAlphabetBuilder<TInput> alphabet) {
             Safe.ArgumentNotNull(alphabet, "alphabet");
+            Safe.ArgumentNotNull(dfaTable, "dfaTable");
 
-            var optimalDFA = new RegularDFADefinition<TInput,TTag>(alphabet, m_initialState);
-
-            Optimize(optimalDFA, InputAlphabet, alphabet, new DummyAlphabet(StateCount), new MapAlphabet<int>()); 
-
+            Optimize(dfaTable, InputAlphabet, alphabet, new DummyAlphabet(StateCount), new MapAlphabet<int>()); 
         }
 
 
--- a/Implab/Automaton/RegularExpressions/Token.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/RegularExpressions/Token.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -10,7 +10,7 @@
             return Cat(new EndToken<TTag>());
         }
 
-        public Token<TTag> Tag<T>(T tag) where T : IConvertible {
+        public Token<TTag> Tag(TTag tag) {
             return Cat(new EndToken<TTag>(tag));
         }
 
@@ -48,11 +48,11 @@
             var token = Repeat(min);
 
             for (int i = min; i < max; i++)
-                token = token.Cat( this.Optional() );
+                token = token.Cat( Optional() );
             return token;
         }
 
-        public static Token<TTag> New<T>(params T[] set) where T : struct, IConvertible {
+        public static Token<TTag> New(params int[] set) {
             Safe.ArgumentNotNull(set, "set");
             Token<TTag> token = null;
             foreach(var c in set.Distinct())
--- a/Implab/Automaton/Scanner.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Automaton/Scanner.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -29,7 +29,7 @@
         protected DFAStateDescriptior<TTag> m_currentState;
         int m_previewCode;
 
-        protected int m_tokenLen = 0;
+        protected int m_tokenLen;
         protected int m_tokenOffset;
 
         protected char[] m_buffer;
@@ -142,18 +142,17 @@
                 if (nextState == DFAConst.UNREACHABLE_STATE) {
                     if (m_currentState.final)
                         return true;
-                    else
-                        throw new ParserException(
-                            String.Format(
-                                "Unexpected symbol '{0}', at pos {1}",
-                                m_buffer[m_pointer],
-                                Position
-                            )
-                        );
-                } else {
-                    m_currentState = m_states[nextState];
-                    m_tokenLen++;
+                    
+                    throw new ParserException(
+                        String.Format(
+                            "Unexpected symbol '{0}', at pos {1}",
+                            m_buffer[m_pointer],
+                            Position
+                        )
+                    );
                 }
+                m_currentState = m_states[nextState];
+                m_tokenLen++;
 
             } while (Shift());
 
@@ -220,6 +219,7 @@
         /// </summary>
         /// <param name="states">Таблица состояний нового ДКА</param>
         /// <param name="alphabet">Таблица входных символов для нового ДКА</param>
+        /// <param name = "initialState"></param>
         protected void Switch(DFAStateDescriptior<TTag>[] states, int[] alphabet, int initialState) {
             Safe.ArgumentNotNull(states, "dfa");
 
--- a/Implab/Formats/ByteAlphabet.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/ByteAlphabet.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
+using Implab.Automaton;
 
-namespace Implab.Automaton {
+namespace Implab.Formats {
     public class ByteAlphabet : IndexedAlphabetBase<byte> {
         public ByteAlphabet() : base(byte.MaxValue + 1){
         }
--- a/Implab/Formats/CharAlphabet.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/CharAlphabet.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,11 +1,8 @@
-using Implab;
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Implab.Automaton;
 
-namespace Implab.Automaton {
+namespace Implab.Formats {
     public class CharAlphabet: IndexedAlphabetBase<char> {
 
         public CharAlphabet()
--- a/Implab/Formats/JSON/JSONElementContext.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JSONElementContext.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,14 +1,8 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.JSON {
+namespace Implab.Formats.JSON {
     /// <summary>
     /// internal
     /// </summary>
-    public enum JSONElementContext {
+    enum JSONElementContext {
         None,
         Object,
         Array,
--- a/Implab/Formats/JSON/JSONElementType.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JSONElementType.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.JSON {
+namespace Implab.Formats.JSON {
     /// <summary>
     /// Тип элемента на котором находится парсер
     /// </summary>
--- a/Implab/Formats/JSON/JSONGrammar.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JSONGrammar.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,8 +1,9 @@
 using System.Linq;
 using Implab.Automaton.RegularExpressions;
+using System;
 
 namespace Implab.Formats.JSON {
-    class JSONGrammar : Grammar<JSONGrammar> {
+    class JSONGrammar : Grammar<char,JSONGrammar.TokenType> {
         public enum TokenType {
             None,
             BeginObject,
@@ -28,8 +29,14 @@
             Exp
         }
 
-        readonly CDFADefinition m_jsonDFA;
-        readonly CDFADefinition m_stringDFA;
+        static Lazy<JSONGrammar> _instance = new Lazy<JSONGrammar>();
+
+        public static JSONGrammar Instance {
+            get { return _instance.Value; }
+        }
+
+        readonly RegularCharDFADefinition<TokenType> m_jsonDFA;
+        readonly RegularCharDFADefinition<TokenType> m_stringDFA;
 
         public JSONGrammar() {
             DefineAlphabet(Enumerable.Range(0, 0x20).Select(x => (char)x));
@@ -80,20 +87,29 @@
                 .Or(unescaped.Closure().Tag(TokenType.UnescapedChar));
                     
 
-            m_jsonDFA = BuildDFA(jsonExpression);
-            m_stringDFA = BuildDFA(jsonStringExpression);
+            m_jsonDFA = new RegularCharDFADefinition<TokenType>(new CharAlphabet()); 
+            BuildDFA(jsonExpression, m_jsonDFA, m_jsonDFA.InputAlphabet);
+
+
+            m_stringDFA = new RegularCharDFADefinition<TokenType>(new CharAlphabet());
+            BuildDFA(jsonStringExpression, m_jsonDFA, m_jsonDFA.InputAlphabet);
         }
 
-        public CDFADefinition JsonDFA {
+        public RegularCharDFADefinition<TokenType> JsonDFA {
             get {
                 return m_jsonDFA;
             }
         }
 
-        public CDFADefinition JsonStringDFA {
+        public RegularDFADefinition<char,TokenType> JsonStringDFA {
             get {
                 return m_stringDFA;
             }
         }
+
+        Token<TokenType> SymbolRangeToken(char start, char stop) {
+            return SymbolToken(Enumerable.Range(start,stop - start).Cast<char>());
+        }
+                
     }
 }
--- a/Implab/Formats/JSON/JSONParser.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JSONParser.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,9 +1,12 @@
-using Implab.Parsing;
-using System;
+using System;
 using System.Diagnostics;
 using System.IO;
+using Implab.Automaton;
+using Implab.Automaton.RegularExpressions;
+using System.Linq;
+using Implab.Components;
 
-namespace Implab.JSON {
+namespace Implab.Formats.JSON {
     /// <summary>
     /// internal
     /// </summary>
@@ -28,53 +31,65 @@
     /// } // Level = 0
     /// </code>
     /// </remarks>
-    public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
+    public class JSONParser : Disposable {
 
         enum MemberContext {
             MemberName,
             MemberValue
         }
 
+        struct ParserContext {
+            DFAStateDescriptior<object>
+        }
+
         static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
-        static readonly DFAStateDescriptior[] _jsonDFA;
-        static readonly DFAStateDescriptior[] _objectDFA;
-        static readonly DFAStateDescriptior[] _arrayDFA;
+        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;
 
         static JSONParser() {
 
 
-            var valueExpression = Token.New(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
-            var memberExpression = Token.New(JsonTokenType.String).Cat(Token.New(JsonTokenType.NameSeparator)).Cat(valueExpression);
+            var valueExpression = Token(JsonTokenType.BeginArray, JsonTokenType.BeginObject, JsonTokenType.Literal, JsonTokenType.Number, JsonTokenType.String);
+            var memberExpression = Token(JsonTokenType.String).Cat(Token(JsonTokenType.NameSeparator)).Cat(valueExpression);
 
             var objectExpression = memberExpression
                 .Cat(
-                    Token.New(JsonTokenType.ValueSeparator)
+                    Token(JsonTokenType.ValueSeparator)
                     .Cat(memberExpression)
                     .EClosure()
                 )
                 .Optional()
-                .Cat(Token.New(JsonTokenType.EndObject))
-                .Tag(0);
+                .Cat(Token(JsonTokenType.EndObject))
+                .Tag(null);
             var arrayExpression = valueExpression
                 .Cat(
-                    Token.New(JsonTokenType.ValueSeparator)
+                    Token(JsonTokenType.ValueSeparator)
                     .Cat(valueExpression)
                     .EClosure()
                 )
                 .Optional()
-                .Cat(Token.New(JsonTokenType.EndArray))
-                .Tag(0);
+                .Cat(Token(JsonTokenType.EndArray))
+                .Tag(null);
 
-            var jsonExpression = valueExpression.Tag(0);
+            var jsonExpression = valueExpression.Tag(null);
 
-            _jsonDFA = BuildDFA(jsonExpression).States;
-            _objectDFA = BuildDFA(objectExpression).States;
-            _arrayDFA = BuildDFA(arrayExpression).States;
+            _jsonDFA = CreateDFA(jsonExpression).GetTransitionTable();
+            _objectDFA = CreateDFA(objectExpression).GetTransitionTable();
+            _arrayDFA = CreateDFA(arrayExpression).GetTransitionTable();
         }
 
-        static EDFADefinition<JsonTokenType> BuildDFA(Token expr) {
-            var builder = new DFABuilder();
-            var dfa = new EDFADefinition<JsonTokenType>(_alphabet);
+        static Token<object> Token(params JsonTokenType[] input) {
+            return Token<object>.New(input.Select(t => _alphabet.Translate(t)).ToArray());
+        }
+
+        static RegularDFADefinition<JsonTokenType,object> CreateDFA(Token<object> expr) {
+            var builder = new RegularDFABuilder<object>();
+            var dfa = new RegularDFADefinition<JsonTokenType,object>(_alphabet);
+
             expr.Accept(builder);
 
             builder.BuildDFA(dfa);
@@ -243,25 +258,13 @@
             }
         }
 
-        protected virtual void Dispose(bool disposing) {
+        protected override void Dispose(bool disposing) {
             if (disposing) {
                 m_scanner.Dispose();
             }
         }
 
         /// <summary>
-        /// Освобождает парсер и связанный с ним сканнер.
-        /// </summary>
-        public void Dispose() {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        ~JSONParser() {
-            Dispose(false);
-        }
-
-        /// <summary>
         /// Переходит в конец текущего объекта.
         /// </summary>
         public void SeekElementEnd() {
--- a/Implab/Formats/JSON/JSONScanner.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JSONScanner.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,25 +1,21 @@
-using Implab.Parsing;
-using System;
-using System.Collections.Generic;
+using System;
 using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using Implab.Automaton;
 
-namespace Implab.JSON {
+namespace Implab.Formats.JSON {
     /// <summary>
     /// Сканнер (лексер), разбивающий поток символов на токены JSON.
     /// </summary>
-    public class JSONScanner : Scanner {
+    public class JSONScanner : Scanner<object> {
         char[] m_stringBuffer;
-        DFAStateDescriptior[] m_stringDFA;
+        DFAStateDescriptior<>[] m_stringDFA;
         int[] m_stringAlphabet;
 
         /// <summary>
         /// Создает новый экземпляр сканнера
         /// </summary>
         public JSONScanner()
-            : base(JSONGrammar.Instance.JsonDFA.States, JSONGrammar.Instance.JsonDFA.Alphabet.GetTranslationMap()) {
+            : base(JSONGrammar.Instance.JsonDFA.GetTransitionTable(), JSONGrammar.Instance.JsonDFA.Alphabet.GetTranslationMap()) {
             m_stringBuffer = new char[1024];
             var dfa = JSONGrammar.Instance.JsonStringDFA;
             m_stringAlphabet = dfa.Alphabet.GetTranslationMap();
--- a/Implab/Formats/JSON/JsonTokenType.cs	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Formats/JSON/JsonTokenType.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Implab.JSON {
+namespace Implab.Formats.JSON {
     /// <summary>
     /// Тип токенов, возвращаемых <see cref="JSONScanner"/>.
     /// </summary>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/RegularCharDFADefinition.cs	Mon Feb 29 02:02:17 2016 +0300
@@ -0,0 +1,17 @@
+using System;
+using Implab.Automaton.RegularExpressions;
+
+namespace Implab.Formats {
+    public class RegularCharDFADefinition<TTag> : RegularDFADefinition<char,TTag>  {
+        readonly CharAlphabet m_alphabet;
+
+        public RegularCharDFADefinition(CharAlphabet alphabet) : base(alphabet) {
+            m_alphabet = alphabet;
+        }
+
+        public new CharAlphabet InputAlphabet {
+            get { return m_alphabet; }
+        }
+    }
+}
+
--- a/Implab/Implab.csproj	Thu Feb 25 02:11:13 2016 +0300
+++ b/Implab/Implab.csproj	Mon Feb 29 02:02:17 2016 +0300
@@ -152,7 +152,6 @@
     <Compile Include="Components\RunnableComponent.cs" />
     <Compile Include="Components\IFactory.cs" />
     <Compile Include="Automaton\DFAStateDescriptor.cs" />
-    <Compile Include="Automaton\DFAutomaton.cs" />
     <Compile Include="Automaton\EnumAlphabet.cs" />
     <Compile Include="Automaton\IAlphabet.cs" />
     <Compile Include="Automaton\ParserException.cs" />
@@ -185,11 +184,12 @@
     <Compile Include="Automaton\MapAlphabet.cs" />
     <Compile Include="Automaton\DummyAlphabet.cs" />
     <Compile Include="Automaton\DFATransitionTable.cs" />
-    <Compile Include="Automaton\IDFATransitionTableBuilder.cs" />
-    <Compile Include="Automaton\IDFATransitionTable.cs" />
     <Compile Include="Automaton\RegularExpressions\RegularDFADefinition.cs" />
     <Compile Include="Formats\CharAlphabet.cs" />
     <Compile Include="Formats\ByteAlphabet.cs" />
+    <Compile Include="Formats\RegularCharDFADefinition.cs" />
+    <Compile Include="Automaton\IDFATable.cs" />
+    <Compile Include="Automaton\IDFATableBuilder.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup />