This subroutine gets the destination index of DFA nodes from the current index with given symbol, adding a DFA node if necessary.
It calculates the set of NFA states that can be reached from the current
node for the given symbol
,
excluding epsilon transitions, and then registers the new DFA state node if it has not already been registered.
Finally, it adds the transition from the current
node to the destination
node in the DFA graph.
In this implementation with array approach, array reduction is done in the reachable procedure.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(automaton_t), | intent(inout) | :: | self | |||
integer(kind=int32), | intent(in) | :: | curr_i | |||
integer(kind=int32), | intent(inout) | :: | dst_i | |||
character(len=*), | intent(in) | :: | symbol |
pure subroutine automaton__construct_dfa (self, curr_i, dst_i, symbol) use :: forgex_lazy_dfa_node_m, only: dfa_transition_t implicit none class(automaton_t), intent(inout) :: self integer(int32), intent(in) :: curr_i integer(int32), intent(inout) :: dst_i character(*), intent(in) :: symbol type(dfa_transition_t) :: d_tra integer(int32) :: prev_i dst_i = DFA_INVALID_INDEX prev_i = curr_i ! ε遷移を除いた行き先のstate_setを取得する。 ! Get the state set for the destination excluding epsilon-transition. d_tra = self%move(prev_i, symbol) ! この実装ではリストのリダクションを計算する必要がない。 !! In this implementation with array approach, array reduction is done in the reachable procedure. ! ε遷移との和集合を取り、d_tra%nfa_setに格納する。 ! Combine the state set with epsilon-transitions and store in `d_tra%nfa_set`. call self%nfa%collect_epsilon_transition(d_tra%nfa_set) ! 空のNFA状態集合の登録を禁止する if (.not. any(d_tra%nfa_set%vec)) then dst_i = DFA_INVALID_INDEX return end if dst_i = self%dfa%registered(d_tra%nfa_set) ! まだDFA状態が登録されていない場合は、新しく登録する。 ! If the destination index is DFA_INVALID_INDEX, register a new DFA node. if (dst_i == DFA_INVALID_INDEX) then call self%register_state(d_tra%nfa_set, dst_i) end if ! If the destination index is DFA_INVALID_INDEX, the registration is failed. if (dst_i == DFA_INVALID_INDEX) error stop "DFA registration failed." if (self%dfa%nodes(prev_i)%is_registered_tra(dst_i, symbol)) return ! 遷移を追加する ! Add a DFA transition from `prev` to `next` for the given `symbol`. call self%dfa%add_transition(d_tra%nfa_set, prev_i, dst_i, & which_segment_symbol_belong(self%all_segments, symbol)) end subroutine automaton__construct_dfa