This subroutine convert an NFA into a fully compiled DFA.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(automaton_t), | intent(inout) | :: | automaton | |||
integer(kind=int32), | intent(in) | :: | curr_i |
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