mark_epsilon_transition Subroutine

private pure recursive subroutine mark_epsilon_transition(nfa_graph, nfa_top, nfa_set, nfa_i)

This subroutine recursively marks empty transitions from a given NFA state index.

Arguments

Type IntentOptional Attributes Name
type(nfa_state_node_t), intent(in) :: nfa_graph(NFA_STATE_BASE:NFA_STATE_LIMIT)
integer(kind=int32), intent(in) :: nfa_top
type(nfa_state_set_t), intent(inout) :: nfa_set
integer(kind=int32), intent(in) :: nfa_i

Source Code

   recursive pure subroutine mark_epsilon_transition(nfa_graph, nfa_top, nfa_set, nfa_i)
      use :: forgex_nfa_node_m, only: nfa_state_node_t
      implicit none
      type(nfa_state_node_t), intent(in)    :: nfa_graph(NFA_STATE_BASE:NFA_STATE_LIMIT)
      type(nfa_state_set_t),  intent(inout) :: nfa_set
      integer(int32),         intent(in)    :: nfa_i, nfa_top

      integer :: dst
      integer :: iii, j

      ! Add the current state to the state set.
      call add_nfa_state(nfa_set, nfa_i)

      ! Scan the entire NFA state nodes.
      outer: do iii = NFA_STATE_BASE+1, nfa_top
         if (.not. allocated(nfa_graph(iii)%forward)) cycle outer

         ! Scan the all forward transitions.
         middle: do j = lbound(nfa_graph(iii)%forward, dim=1), nfa_graph(iii)%forward_top

            ! If the forward segment list is not allocated, move to the next loop.
            if (.not. allocated(nfa_graph(iii)%forward(j)%c)) cycle middle

            ! Get the destination index and if it is not NULL, call this function recursively.
            dst = nfa_graph(iii)%forward(j)%dst
            if (dst /= NFA_NULL_TRANSITION) call mark_epsilon_transition(nfa_graph, nfa_top, nfa_set, nfa_i)

         end do middle
      end do outer
   end subroutine mark_epsilon_transition