get_suffix_literal_internal Subroutine

private pure recursive subroutine get_suffix_literal_internal(tree, idx, suffix, has_or, has_closure)

Arguments

Type IntentOptional Attributes Name
type(tree_node_t), intent(in) :: tree(:)
integer(kind=int32), intent(in) :: idx
character(len=:), intent(inout), allocatable :: suffix
logical, intent(inout) :: has_or
logical, intent(inout) :: has_closure

Source Code

   pure recursive subroutine get_suffix_literal_internal(tree, idx, suffix,  has_or, has_closure)
      implicit none
      type(tree_node_t), intent(in) :: tree(:)
      integer(int32), intent(in) :: idx
      character(:), allocatable, intent(inout) :: suffix
      logical, intent(inout) :: has_or, has_closure
      
      logical :: or_r, or_l, closure_r, closure_l
      type(tree_node_t) :: node, parent
      character(:), allocatable :: candidate1, candidate2
      integer :: n, j

      if (idx < 1) return
      node = tree(idx)
      candidate1 = ''
      candidate2 = ''
      or_l = .false.
      or_r = .false.
      closure_l = .false.
      closure_r = .false.

      if (idx < 1) return

      select case (node%op)
      case (op_concat)
         call get_suffix_literal_internal(tree, node%right_i, suffix, or_r, closure_r)

         if(.not. or_r) call get_suffix_literal_internal(tree, node%left_i, candidate1, or_l, closure_l)

         has_or = or_l .or. or_r
         has_closure =  closure_r
         if (or_r .and. or_l) then
            return
         else if (or_r) then
            return
         else if (closure_l) then
            return
         else if (closure_r) then
            suffix = suffix
         else
            suffix = candidate1//suffix
            return
         end if
   
      case (op_union) !OR
         call get_suffix_literal_internal(tree, node%left_i, candidate1, or_l, has_closure)
         call get_suffix_literal_internal(tree, node%right_i, candidate2, or_r, has_closure)

         suffix = extract_same_part_suffix(candidate1, candidate2)

         has_or = .true.

      case(op_repeat)
         n = node%min_repeat
         do j = 1, n
            call get_suffix_literal_internal(tree, node%left_i, suffix, or_l, has_closure)
            has_or = or_l .or. has_or
         end do

         if (node%min_repeat /= node%max_repeat) has_closure = .true.

      case(op_closure)
         has_closure = .true.
         if(node%parent_i == 0) return
         parent = tree(node%parent_i)

         ! Processing the + operator
         ! Get the left of the parent node, and if it has the same suffix as the current node, return it.
         if (parent%own_i /= 0) then
            if (parent%op == op_concat) then
               if (parent%right_i == node%own_i) then
                  call get_suffix_literal_internal(tree, parent%left_i, candidate1, or_l, closure_l)
                  call get_suffix_literal_internal(tree, node%left_i, candidate2, or_r, closure_r)
                  if (candidate1 == candidate2) then
                     suffix = candidate1
                  end if
               end if
            end if
         end if
         has_or = or_l .or. or_r

      case default
         if (is_literal_tree_node(node)) then
            suffix = char_utf8(node%c(1)%min)//suffix
         else if (is_char_class_tree_node(node)) then
            has_or = .true.
         end if
      end select
   end subroutine get_suffix_literal_internal