pure recursive subroutine get_prefix_literal_internal(tree, idx, prefix, res)
use :: forgex_parameters_m
implicit none
type(tree_node_t), intent(in) :: tree(:)
integer(int32), intent(in) :: idx
character(:), allocatable, intent(inout) :: prefix
logical, intent(inout) :: res
logical :: res_left, res_right, unused
type(tree_node_t) :: node
character(:), allocatable :: candidate1, candidate2
integer :: j, n
if (idx < 1) return
node = tree(idx)
res_left = .false.
res_right = .false.
candidate1 = ''
candidate2 = ''
select case (node%op)
case (op_concat)
call get_prefix_literal_internal(tree, node%left_i, candidate1, res_left)
if (res_left) then
call get_prefix_literal_internal(tree, node%right_i, candidate2, res_right)
end if
prefix = prefix//candidate1//candidate2
res = res_left .and. res_right
case(op_union)
call get_prefix_literal_internal(tree, node%left_i, candidate1, unused)
call get_prefix_literal_internal(tree, node%right_i, candidate2, unused)
prefix = extract_same_part_prefix(candidate1, candidate2)
res = .false.
case(op_repeat)
n = node%min_repeat
do j = 1, n
call get_prefix_literal_internal(tree, node%left_i, prefix, res_left)
end do
res = res_left
case (op_char)
if (is_literal_tree_node(node)) then
if (node%c(1)%min == node%c(1)%max) then
prefix = prefix//adjustl_multi_byte(char_utf8(node%c(1)%min))
res = .true.
return
end if
end if
res = .false.
case default
res = .false.
end select
end subroutine get_prefix_literal_internal