private pure function parse_stream_name(stream_name) result(var_info_list)
Parse a stream name, which consists of one or more stream name fragments, and return the corresponding variable information
as a list of var_info_type. Multiple stream name fragments should be separated by "+" (i.e., a plus, meaning "addition"
operation) or "-" (i.e., a minus, meaning "subtraction" operation).
A stream name fragment can be a predefined stream name (e.g., "invariant", "input", etc.) or a single variable name.
For example, a stream name of "invariant+input+restart" means the union of variables in the "invariant", "input", and
"restart" streams.
Duplicate variable information in the resulting list is discarded.
(KCW, 2024-06-01)
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
pure function parse_stream_name(stream_name)result(var_info_list)character(*),intent(in)::stream_nametype(var_info_type),allocatable::var_info_list(:)character(*),parameter::supported_stream_name_operator='+-'character(1)::stream_name_operatorcharacter(:),allocatable::stream_name_fragmentcharacter(len(invariant_var_info_list%name)),allocatable::var_name_list(:)integer::i,j,n,offsettype(var_info_type),allocatable::var_info_list_buffer(:)n=len_trim(stream_name)if(n==0)then! Empty character string means empty list.var_info_list=parse_stream_name_fragment('')return end ifi=scan(stream_name,supported_stream_name_operator)if(i==0)then! No operators are present in the stream name. It is just a single stream name fragment.stream_name_fragment=stream_namevar_info_list=parse_stream_name_fragment(stream_name_fragment)return end ifoffset=0var_info_list=parse_stream_name_fragment('')do while(.true.)! Extract operator from the stream name.if(offset>0)thenstream_name_operator=stream_name(offset:offset)elsestream_name_operator='+'end if! Extract stream name fragment from the stream name.if(i>1)thenstream_name_fragment=stream_name(offset+1:offset+i-1)elsestream_name_fragment=''end if! Process the stream name fragment according to the operator.if(len_trim(stream_name_fragment)>0)thenvar_info_list_buffer=parse_stream_name_fragment(stream_name_fragment)select case(stream_name_operator)case('+')var_info_list=[var_info_list,var_info_list_buffer]case('-')do j=1,size(var_info_list_buffer)var_name_list=var_info_list%namevar_info_list=pack(var_info_list,var_name_list/=var_info_list_buffer(j)%name)end do case default! Do nothing for unknown operators. Should not happen at all.end select end ifoffset=offset+i! Terminate loop when everything in the stream name has been processed.if(offset+1>n)then exit end ifi=scan(stream_name(offset+1:),supported_stream_name_operator)! Run the loop one last time for the remaining stream name fragment.if(i==0)theni=n-offset+1end if end do! Discard duplicate variable information by names.var_name_list=var_info_list%namevar_info_list=var_info_list(index_unique(var_name_list))end function parse_stream_name