construct_dense_dfa Subroutine

public pure subroutine construct_dense_dfa(automaton, curr_i)

This subroutine convert an NFA into a fully compiled DFA.

Arguments

Type IntentOptional Attributes Name
type(automaton_t), intent(inout) :: automaton
integer(kind=int32), intent(in) :: curr_i

Source Code

   pure subroutine construct_dense_dfa(automaton, curr_i)
      use :: forgex_segment_m, only: SEG_EPSILON, operator(/=)
      implicit none
      type(automaton_t), intent(inout) :: automaton
      integer(int32), intent(in) :: curr_i

      ! Already automaton is initialized
      type(dfa_transition_t) :: d_tra
      integer :: dst_i, i, j, k, ii

      i =  curr_i
      outer: do while (i < automaton%dfa%dfa_top)
         d_tra = move(automaton, i)
         call automaton%nfa%collect_epsilon_transition(d_tra%nfa_set)

         if (.not. any(d_tra%nfa_set%vec)) then
            i = i + 1
            cycle
         end if

         dst_i = automaton%dfa%registered(d_tra%nfa_set)

         if (dst_i == DFA_INVALID_INDEX) then
            call automaton%register_state(d_tra%nfa_set, dst_i)
         end if

         if (dst_i == DFA_INVALID_INDEX) error stop "DFA registration failed."

         middle: do ii = 1, automaton%nfa%nfa_top

            if (.not. allocated(automaton%nfa%nodes(ii)%forward))  cycle middle

            inner: do j = 1, automaton%nfa%nodes(ii)%forward_top

               if (automaton%nfa%nodes(ii)%forward(j)%dst == NFA_NULL_TRANSITION) cycle middle


               if (check_nfa_state(d_tra%nfa_set, automaton%nfa%nodes(ii)%forward(j)%dst)) then
                  core: do k = 1, automaton%nfa%nodes(ii)%forward(j)%c_top
                     if (automaton%nfa%nodes(ii)%forward(j)%c(k) /= SEG_EPSILON) then
                        call automaton%dfa%add_transition(d_tra%nfa_set, i, dst_i, &
                              automaton%nfa%nodes(ii)%forward(j)%c(k))
                     end if
                  end do core
               end if

            end do inner
         end do middle

         i = i + 1
      end do outer
   end subroutine construct_dense_dfa