Tidying up
authorNick Downing <downing.nick@gmail.com>
Sun, 22 Jul 2018 06:30:15 +0000 (16:30 +1000)
committerNick Downing <downing.nick@gmail.com>
Sun, 22 Jul 2018 08:18:23 +0000 (18:18 +1000)
flex_dfa.py

index b742740..ff85938 100644 (file)
@@ -69,7 +69,7 @@ class FlexDFA:
     self.acclist = numpy.zeros((0x100,), numpy.int16)
     n_acclist = 0
     self.accept = numpy.zeros((0x100,), numpy.int16)
-    n_accept = 1
+    n_states = 1
 
     # transitions[i, j] is transition on character j in state i
     # in our way of thinking, 0 is don't care and -1 is failure
@@ -79,15 +79,15 @@ class FlexDFA:
     transitions = numpy.zeros((0x100, 0x101), numpy.int16)
 
     # generate acclist, accept and transition tables
-    while n_accept < len(flex_state_to_action):
-      action = flex_state_to_action[n_accept]
+    while n_states < len(flex_state_to_action):
+      action = flex_state_to_action[n_states]
       state, transition = _dfa.actions[action]
-      #print('state', n_accept, 'transition', transition)
+      #print('state', n_states, 'transition', transition)
 
       del threads0[prefix_slop:]
       transit(transition)
       #print(threads0[prefix_slop:])
-      if n_accept >= self.accept.shape[0]:
+      if n_states >= self.accept.shape[0]:
         # extend accept
         new_accept = numpy.zeros(
           (self.accept.shape[0] * 2,),
@@ -95,12 +95,12 @@ class FlexDFA:
         )
         new_accept[:self.accept.shape[0]] = self.accept
         self.accept = new_accept
-      self.accept[n_accept] = n_acclist
+      self.accept[n_states] = n_acclist
       for k in [j for i in threads0[prefix_slop:] for j in i]:
         acc = k >> 1
         if k & 1:
           if (
-            n_acclist == self.accept[n_accept] or
+            n_acclist == self.accept[n_states] or
             self.acclist[n_acclist - 1] != acc | FlexDFA.YY_TRAILING_HEAD_MASK
           ):
             # look back to start of trailing context, then accept
@@ -121,7 +121,7 @@ class FlexDFA:
         n_acclist += 1
 
       # calculate transition row from _dfa.state character-to-action table
-      if n_accept >= transitions.shape[0]:
+      if n_states >= transitions.shape[0]:
         # extend transitions
         new_transitions = numpy.zeros(
           (transitions.shape[0] * 2, 0x101),
@@ -140,31 +140,31 @@ class FlexDFA:
           next_flex_state = len(flex_state_to_action)
           action_to_flex_state[next_action] = next_flex_state
           flex_state_to_action.append(next_action)
-        transitions[n_accept, character0:character1] = next_flex_state
+        transitions[n_states, character0:character1] = next_flex_state
         character0 = character1
       assert character0 == 0x100
 
-      n_accept += 1
-
-    # remap NUL transitions to 0x100 and replace with EOB transitions
-    transitions[:, 0x100] = transitions[:, 0]
-    transitions[:, 0] = eob_state
+      n_states += 1
 
     # finalize the acclist and accept tables
     self.acclist = self.acclist[:n_acclist]
-    if n_accept >= self.accept.shape[0]:
+    if n_states >= self.accept.shape[0]:
       new_accept = numpy.zeros(
         (self.accept.shape[0] * 2,),
         numpy.int16
       )
       new_accept[:self.accept.shape[0]] = self.accept
       self.accept = new_accept
-    self.accept[n_accept] = n_acclist
-    self.accept = self.accept[:n_accept + 1]
+    self.accept[n_states] = n_acclist
+    self.accept = self.accept[:n_states + 1]
+
+    # finalize the transitions table
+    transitions = transitions[:n_states, :]
+    transitions[:, 0x100] = transitions[:, 0]
+    transitions[:, 0] = eob_state
 
     # state 0 is the jam state, the EOB state will be added later on
-    self.states = numpy.zeros((0x100, 2), numpy.int16) # base, def
-    n_states = 1
+    self.states = numpy.zeros((n_states, 2), numpy.int16) # base, def
     self.entries = numpy.full((0x200, 2), -1, numpy.int16) # nxt, chk
     self.entries[:0x101, :] = 0 # jam state just returns to jam state
     self.entries[0, 0] = eob_state # except for the EOB transition
@@ -177,17 +177,17 @@ class FlexDFA:
       transitions[:, numpy.newaxis, :] != transitions[numpy.newaxis, :, :],
       2
     )
-    while n_states < n_accept:
+    for i in range(1, n_states):
       # find most similar/earliest existing state to use as default
-      default_state = numpy.argmin(dist[:n_states, n_states], 0)
+      state_done = numpy.argmin(dist[:i, i], 0)
       indices = numpy.nonzero(
-        transitions[n_states] != transitions[default_state]
+        transitions[i, :] != transitions[state_done, :]
       )[0]
       if indices.shape[0] == 0:
         # when copying another state, need to have the same base, though
         # the base will not matter since there will be no entries, it is
         # is because of the awkward way the compressed lookup is written
-        start_index = self.states[default_state, 0]
+        start_index = self.states[state_done, 0]
       else:
         # make sure entries array is at least large enough to find a spot
         while self.entries.shape[0] < n_entries + 0x101:
@@ -214,26 +214,17 @@ class FlexDFA:
           if not numpy.any(entries_used[indices + start_index]):
             break
           start_index += 1
-        self.entries[indices + start_index, 0] = transitions[n_states, indices]
-        self.entries[indices + start_index, 1] = n_states
+        self.entries[indices + start_index, 0] = transitions[i, indices]
+        self.entries[indices + start_index, 1] = i
         entries_used[indices + start_index] = True
         if n_entries < start_index + 0x101:
           n_entries = start_index + 0x101
 
-      if n_states >= self.states.shape[0]:
-        new_states = numpy.zeros(
-          (self.states.shape[0] * 2, 2),
-          numpy.int16
-        )
-        new_states[:self.states.shape[0], :] = self.states
-        self.states = new_states
-      self.states[n_states, 0] = start_index
-      self.states[n_states, 1] = default_state
-      n_states += 1
+      self.states[i, 0] = start_index
+      self.states[i, 1] = state_done
 
-    # finalize states and entries tables
+    # finalize entries table
     self.entries = self.entries[:n_entries, :]
-    self.states = self.states[:n_states, :]
 
 def generate(plex, skel_file, out_file):
   nfa = plex.to_nfa()