do_find_match_dense_dfa Subroutine

public subroutine do_find_match_dense_dfa(flags, pattern, text, is_exactly)

Uses

Arguments

Type IntentOptional Attributes Name
logical, intent(in) :: flags(:)
character(len=*), intent(in) :: pattern
character(len=*), intent(in) :: text
logical, intent(in) :: is_exactly

Source Code

   subroutine do_find_match_dense_dfa(flags, pattern, text, is_exactly)
      use :: forgex_automaton_m
      use :: forgex_syntax_tree_graph_m
      use :: forgex_cli_memory_calculation_m
      use :: forgex_cli_time_measurement_m
      use :: forgex_dense_dfa_m
      use :: forgex_nfa_state_set_m
      use :: forgex_cli_utils_m
      use :: forgex_utility_m
      implicit none
      logical, intent(in) :: flags(:)
      character(*), intent(in) :: pattern
      character(*), intent(in) :: text
      logical, intent(in) :: is_exactly

      type(tree_t) :: tree
      type(automaton_t) :: automaton

      integer :: uni, ierr, i
      character(:), allocatable :: dfa_for_print
      character(256) :: line
      real(real64) :: lap1, lap2, lap3, lap4, lap5
      logical :: res
      integer :: from, to
      from = 0
      to = 0

      if (flags(FLAG_HELP) .or. pattern == '') call print_help_find_match_dense_dfa
      if (flags(FLAG_NO_LITERAL)) call info("No literal search optimization is implemented in dense DFA.")
      call time_begin()
      ! call build_syntax_tree(trim(pattern), tape, tree, root)
      call tree%build(trim(pattern))
      lap1 = time_lap()

      call automaton%preprocess(tree)
      lap2 = time_lap() ! build nfa

      call automaton%init()
      lap3 = time_lap() ! automaton initialize

      call construct_dense_dfa(automaton, automaton%initial_index)
      lap4 = time_lap() ! compile nfa to dfa

      if (is_exactly) then
         res = match_dense_dfa_exactly(automaton, text)
         if (res) then
            from = 1
            to = len(text)
         end if
      else
         block
            call match_dense_dfa_including(automaton, char(10)//text//char(10), from, to)
            if (is_there_caret_at_the_top(pattern)) then
               from = from
            else
               from = from -1
            end if

            if (is_there_dollar_at_the_end(pattern)) then
               to = to -2
            else
               to = to -1
            end if

            if (from>0 .and. to>0) then
               res = .true.
            else
               res = .false.
            end if
         end block
      end if
      lap5 = time_lap() ! search time

      open(newunit=uni, status='scratch')
      write(uni, fmta) HEADER_NFA
      call automaton%nfa%print(uni, automaton%nfa_exit)
      write(uni, fmta) HEADER_DFA
      call automaton%print_dfa(uni)

      rewind(uni)
      ierr = 0
      dfa_for_print = ''
      do while (ierr == 0)
         read(uni, fmta, iostat=ierr) line
         if (ierr/=0) exit
         if (get_os_type() == OS_WINDOWS) then
            dfa_for_print = dfa_for_print//trim(line)//CRLF
         else
            dfa_for_print = dfa_for_print//trim(line)//LF
         end if
      end do
      close(uni)

      output: block
         character(NUM_DIGIT_KEY) :: pattern_key, text_key
         character(NUM_DIGIT_KEY) :: parse_time, nfa_time, dfa_init_time, dfa_compile_time, matching_time
         character(NUM_DIGIT_KEY) :: memory
         character(NUM_DIGIT_KEY) :: tree_count, nfa_count, dfa_count
         character(NUM_DIGIT_KEY) :: matching_result
         character(NUM_DIGIT_KEY) :: cbuff(12) = ''
         integer :: memsiz

         pattern_key    = "pattern:"
         text_key       = "text:"
         parse_time     = "parse time:"
         nfa_time       = "compile nfa time:"
         dfa_init_time  = "dfa initialize time:"
         dfa_compile_time = "compile dfa time:"
         matching_time  = "search time:"
         memory         = "memory (estimated):"
         matching_result= "matching result:"

         tree_count     = "tree node count:"
         nfa_count      = "nfa states:"
         dfa_count      = "dfa states:"

         memsiz = mem_tape(tree%tape) + mem_tree(tree%nodes) + mem_nfa_graph(automaton%nfa) &
            + mem_dfa_graph(automaton%dfa) + 4*3
         if (allocated(automaton%entry_set%vec)) then
            memsiz = memsiz + size(automaton%entry_set%vec, dim=1)
         end if
         if (allocated(automaton%all_segments)) then
            memsiz = memsiz + size(automaton%all_segments, dim=1)*8
         end if

         if (flags(FLAG_VERBOSE)) then
            cbuff = [pattern_key, text_key, parse_time, nfa_time, dfa_init_time, dfa_compile_time, matching_time,&
                     matching_result, memory, tree_count, nfa_count, dfa_count]
            call right_justify(cbuff)

            write(stdout, '(a, 1x, a)') trim(cbuff(1)), trim(adjustl(pattern))
            write(stdout, '(a, 1x, a)') trim(cbuff(2)), "'"//text_highlight_green(text,from,to)//"'"
            write(stdout, fmt_out_time) trim(cbuff(3)), get_lap_time_in_appropriate_unit(lap1)
            write(stdout, fmt_out_time) trim(cbuff(4)), get_lap_time_in_appropriate_unit(lap2)
            write(stdout, fmt_out_time) trim(cbuff(5)), get_lap_time_in_appropriate_unit(lap3)
            write(stdout, fmt_out_time) trim(cbuff(6)), get_lap_time_in_appropriate_unit(lap4)
            write(stdout, fmt_out_time) trim(cbuff(7)), get_lap_time_in_appropriate_unit(lap5)
            write(stdout, fmt_out_logi) trim(cbuff(8)), res
            write(stdout, fmt_out_int) trim(cbuff(9)), memsiz
            write(stdout, fmt_out_ratio) trim(cbuff(10)), tree%top, size(tree%nodes, dim=1)
            write(stdout, fmt_out_ratio) trim(cbuff(11)), automaton%nfa%nfa_top, automaton%nfa%nfa_limit
            write(stdout, fmt_out_ratio) trim(cbuff(12)), automaton%dfa%dfa_top, automaton%dfa%dfa_limit
         else if (flags(FLAG_NO_TABLE)) then
            continue
         else
            cbuff = [pattern_key, text_key, parse_time, nfa_time, dfa_init_time, dfa_compile_time, matching_time,&
            matching_result, memory, (repeat(" ", NUM_DIGIT_KEY), i = 1, 3)]
            call right_justify(cbuff)

            write(stdout, '(a, 1x, a)') trim(cbuff(1)), trim(adjustl(pattern))
            write(stdout, '(a, 1x, a)') trim(cbuff(2)), "'"//text_highlight_green(text,from,to)//"'"
            write(stdout, fmt_out_time) trim(cbuff(3)), get_lap_time_in_appropriate_unit(lap1)
            write(stdout, fmt_out_time) trim(cbuff(4)), get_lap_time_in_appropriate_unit(lap2)
            write(stdout, fmt_out_time) trim(cbuff(5)), get_lap_time_in_appropriate_unit(lap3)
            write(stdout, fmt_out_time) trim(cbuff(6)), get_lap_time_in_appropriate_unit(lap4)
            write(stdout, fmt_out_time) trim(cbuff(7)), get_lap_time_in_appropriate_unit(lap5)
            write(stdout, fmt_out_logi) trim(cbuff(8)), res
            write(stdout, fmt_out_int) trim(cbuff(9)), memsiz
         end if

         if (flags(FLAG_TABLE_ONLY))  then
            call automaton%free()
            return
         end if

         write(stdout, *) ""
         write(stdout, fmta, advance='no') trim(dfa_for_print)
         write(stdout, fmta) FOOTER
      end block output

      call automaton%free()

   end subroutine do_find_match_dense_dfa