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