Hm, what are your datatypes? Is this ONLY text, or are you able to impose your own structure?
You could have something like this:
-- Instantiated Container Packages.
Package String_Holder is new Ada.Containers.Indefinite_Holders(
Element_Type => String,
"=" => Ada.Strings.Equal_Case_Insensitive
);
Package String_Map is new Ada.Containers.Indefinite_Ordered_Maps(
"<" => Ada.Strings.Less_Case_Insensitive,
"=" => Ada.Strings.Equal_Case_Insensitive,
Key_Type => String,
Element_Type => String
);
-- The heart of the operating program.
With String_Holder, String_Map;
Package Acronyms is
-- Because this is it's own type, you can put other things in the record, like a link to the place that it's defined, if needed.
Type Initialism is new String_Holder.Holder with null record;
Function Expand( Acronym : Initialism ) return String;
Procedure Register( Acronym, Expansion : String );
--...
End Acronyms;
Package Body Acronyms is
Acronym_Map : String_Map.Map;
Procedure Register( Acronym, Expansion : String ) is
Begin
Acronym_Map.Insert( New_Item => Expansion, Key => Acronym );
End Register;
Function Expand( Acronym : Initialism ) return String is
Begin
Return Acronym_Map( Acronym );
Exception
when others => Return Acronym; -- I forget if it's CONSTRAINT_ERROR or ASSERT_ERROR when the element is not present.
End Expand;
End Acronyms;
-- in your main Acronym-Stream package...
-- Text_Soup is a variant record for handling portions of an acronym-expanding string; your main data-structure would probably be an Indefinite_Vector of Text_Soup'Class,
-- you might not need Input or output, depending on your usage, but for automatically expanding the initialism you'd need to use Acronyms.Expand.
Type Text_Soup(<>) is tagged private;
procedure Output(
Stream : not null access Ada.Streams.Root_Stream_Type'Class;
Item : in Text_Soup'Class);
function Input(
Stream : not null access Ada.Streams.Root_Stream_Type'Class)
return Text_Soup'Class;
-- Other public operations.
PRIVATE
For Text_Soup'Class'Input use Input;
For Text_Soup'Class'Output use Output;
Type Text_Soup(Length : Natural) is record
case Length is
when 0 => Acronym : Initialism;
when others => Text : String(1..Length);
end case;
end record;
--...