diff Implab/Formats/InputScanner.cs @ 228:6fa235c5a760 v2

Rewritten JsonScanner, JsonParser, fixed naming style
author cin
date Tue, 12 Sep 2017 01:19:12 +0300
parents
children 5f7a3e1d32b9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Formats/InputScanner.cs	Tue Sep 12 01:19:12 2017 +0300
@@ -0,0 +1,84 @@
+using Implab.Automaton;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Implab.Formats {
+    public class InputScanner<TTag> {
+        readonly TTag[] m_tags;
+        readonly int m_initialState;
+        readonly int[,] m_dfa;
+        readonly CharMap m_alphabet;
+        readonly bool[] m_final;
+
+        int m_position;
+        int m_state;
+
+        public InputScanner(int[,] dfaTable, bool[] finalStates, TTag[] tags, int initialState, CharMap alphabet) {
+            Safe.ArgumentNotNull(dfaTable, nameof(dfaTable));
+            Safe.ArgumentNotNull(finalStates, nameof(finalStates));
+            Safe.ArgumentNotNull(tags, nameof(tags));
+            Safe.ArgumentNotNull(alphabet, nameof(alphabet));
+
+            m_dfa = dfaTable;
+            m_final = finalStates;
+            m_tags = tags;
+            m_initialState = initialState;
+            m_alphabet = alphabet;
+        }
+
+        public TTag Tag {
+            get {
+                return m_tags[m_state];
+            }
+        }
+
+        public int Position {
+            get {
+                return m_position;
+            }
+        }
+
+        public bool IsFinal {
+            get {
+                return m_final[m_state];
+            }
+        }
+
+        public void Reset() {
+            m_state = m_initialState;
+        }
+
+        public InputScanner<TTag> Clone() {
+            var clone = new InputScanner<TTag>(m_dfa, m_final, m_tags, m_initialState, m_alphabet);
+            clone.m_state = m_state;
+            clone.m_position = m_position;
+            return clone;
+        }
+
+        public bool Scan(char[] data, int offset, int length) {
+            if (length <= 0) {
+                m_position = offset;
+                return false; // EOF
+            }
+
+            var max = offset + length;
+            var next = m_state;
+
+            while(offset < max) {
+                next = m_dfa[next, m_alphabet.Translate(data[offset])];
+                if (next == AutomatonConst.UNREACHABLE_STATE) {
+                    // scanner stops on the next position after last recognized symbol
+                    m_position = offset;
+                    return false;
+                }
+                m_state = next;
+                offset++;
+            }
+            m_position = offset;
+            return true;
+        }
+    }
+}