do_find_match_lazy_dfa Subroutine

public subroutine do_find_match_lazy_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_lazy_dfa(flags, pattern, text, is_exactly)
      use :: forgex_automaton_m
      use :: forgex_syntax_tree_graph_m
      use :: forgex_syntax_tree_optimize_m
      use :: forgex_cli_memory_calculation_m
      use :: forgex_api_internal_m
      use :: forgex_nfa_state_set_m
      use :: forgex_cli_utils_m
      use :: forgex_utility_m, only: is_there_caret_at_the_top, is_there_dollar_at_the_end
      use :: forgex_parameters_m, only: ACCEPTED_EMPTY
      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, prefix, suffix, entire
      character(256) :: line
      real(real64) :: lap1, lap2, lap3, lap4, lap5
      logical :: res, flag_runs_engine, flag_fixed_string
      integer :: from, to

      dfa_for_print = ''
      lap1 = 0d0
      lap2 = 0d0
      lap3 = 0d0
      lap4 = 0d0
      lap5 = 0d0
      from = 0
      to = 0
      prefix = ''
      suffix = ''
      entire = ''
      flag_fixed_string = .false.
      flag_runs_engine = .false.

      if (flags(FLAG_HELP) .or. pattern == '') call print_help_find_match_lazy_dfa


      call time_begin()
      call tree%build(trim(pattern))
      lap1 = time_lap()


      call time_begin()
      if (.not. flags(FLAG_NO_LITERAL)) then
         entire = get_entire_literal(tree)
         if (entire /= '') flag_fixed_string = .true.

         if (.not. flag_fixed_string) then
            prefix = get_prefix_literal(tree)
            suffix = get_suffix_literal(tree)
         end if
      end if
      lap5 = time_lap()

      if (.not. flag_fixed_string) then
         call automaton%preprocess(tree)
         lap2 = time_lap()

         call automaton%init()
         lap3 = time_lap()
      end if

      if (is_exactly) then

         if (flag_fixed_string) then
            if (len(text) == len(entire)) then
               res = text == entire
            end if
         else
            call runner_do_matching_exactly(automaton, text, res, prefix, suffix, flags(FLAG_NO_LITERAL), flag_runs_engine)
         end if

         lap4 = time_lap()
         if (res) then
            from = 1
            to = len(text)
         end if
      else
         block
            if (flag_fixed_string) then
               from = index(text, entire)
               if (from > 0 ) to = from + len(entire) -1
            else
               call runner_do_matching_including(automaton, text, from, to, &
                     prefix, suffix, flags(FLAG_NO_LITERAL), flag_runs_engine)
            end if

            if (from > 0 .and. to > 0) then
               res = .true.
            else if (from == ACCEPTED_EMPTY .and. to == ACCEPTED_EMPTY) then
               res = .true.
            else
               res = .false.
            end if

            lap4 = time_lap()

         end block
      end if

      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
      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, extract_time
         character(NUM_DIGIT_KEY) :: nfa_time, dfa_init_time, matching_time, memory
         character(NUM_DIGIT_KEY) :: runs_engine_key
         character(NUM_DIGIT_KEY) :: tree_count
         character(NUM_DIGIT_KEY) :: nfa_count
         character(NUM_DIGIT_KEY) :: dfa_count, matching_result
         character(NUM_DIGIT_KEY) :: cbuff(13) = ''
         integer :: memsiz

         pattern_key    = "pattern:"
         text_key       = "text:"
         parse_time     = "parse time:"
         extract_time   = "extract literal time:"
         runs_engine_key= "runs engine:"

         nfa_time       = "compile nfa time:"
         dfa_init_time  = "dfa initialize 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:"

         if (flag_fixed_string) then
            memsiz = mem_tape(tree%tape) + mem_tree(tree%nodes)
         else
            memsiz = mem_tape(tree%tape) + mem_tree(tree%nodes) + mem_nfa_graph(automaton%nfa) &
                      + mem_dfa_graph(automaton%dfa) + 4*3
         end if

         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, extract_time, runs_engine_key, &
                     nfa_time, dfa_init_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//'"'
            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(lap5)
            write(stdout, fmt_out_logi) trim(cbuff(5)), flag_runs_engine

            if (flag_runs_engine .or. .not. flag_fixed_string) then
               write(stdout, fmt_out_time) trim(cbuff(6)), get_lap_time_in_appropriate_unit(lap2)
               write(stdout, fmt_out_time) trim(cbuff(7)), get_lap_time_in_appropriate_unit(lap3)
            else
               write(stdout, fmt_out_char) trim(cbuff(6)), not_running
               write(stdout, fmt_out_char) trim(cbuff(7)), not_running
            end if

            write(stdout, fmt_out_time) trim(cbuff(8)), get_lap_time_in_appropriate_unit(lap4)
            write(stdout, fmt_out_logi) trim(cbuff(9)), res
            write(stdout, fmt_out_int)  trim(cbuff(10)), memsiz

            write(stdout, fmt_out_ratio) trim(cbuff(11)), tree%top, size(tree%nodes, dim=1)
            write(stdout, fmt_out_ratio) trim(cbuff(12)), automaton%nfa%nfa_top, automaton%nfa%nfa_limit
            write(stdout, fmt_out_ratio) trim(cbuff(13)), automaton%dfa%dfa_top, automaton%dfa%dfa_limit
         else if (flags(FLAG_NO_TABLE)) then
            continue
         else
            cbuff(:) = [pattern_key, text_key, parse_time, extract_time, runs_engine_key, nfa_time, dfa_init_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)), pattern
            ! write(stdout, '(a,1x,a)') trim(cbuff(2)), "'"//text//"'"
            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(lap5)
            write(stdout, fmt_out_logi) trim(cbuff(5)), flag_runs_engine

            if (flag_runs_engine .or. .not. flag_fixed_string) then
               write(stdout, fmt_out_time) trim(cbuff(6)), get_lap_time_in_appropriate_unit(lap2)
               write(stdout, fmt_out_time) trim(cbuff(7)), get_lap_time_in_appropriate_unit(lap3)
            else
               write(stdout, fmt_out_char) trim(cbuff(6)), not_running
               write(stdout, fmt_out_char) trim(cbuff(7)), not_running
            end if

            write(stdout, fmt_out_time) trim(cbuff(8)), get_lap_time_in_appropriate_unit(lap4)
            write(stdout, fmt_out_logi) trim(cbuff(9)), res
            write(stdout, fmt_out_int)  trim(cbuff(10)), memsiz
         end if

         if (flags(FLAG_TABLE_ONLY) .or. .not. flag_runs_engine .or. flag_fixed_string) 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_lazy_dfa