diff options
author | Jed Barber <jjbarber@y7mail.com> | 2020-05-22 22:42:25 +1000 |
---|---|---|
committer | Jed Barber <jjbarber@y7mail.com> | 2020-05-22 22:42:25 +1000 |
commit | 6b3a2f0ce7c8c3aae32811936441277728f69a6b (patch) | |
tree | 707ee82ef74311f9e6a5f9054ab289e598ecbc30 | |
parent | 853a5a484f3e556a526473f23a60e3394b133abe (diff) |
Apparently I lied, also old Graphs package removed
-rw-r--r-- | src/packrat-graphs.adb | 1128 | ||||
-rw-r--r-- | src/packrat-graphs.ads | 657 | ||||
-rw-r--r-- | src/packrat-parse_graphs.ads | 9 |
3 files changed, 9 insertions, 1785 deletions
diff --git a/src/packrat-graphs.adb b/src/packrat-graphs.adb deleted file mode 100644 index 10e130f..0000000 --- a/src/packrat-graphs.adb +++ /dev/null @@ -1,1128 +0,0 @@ - - -with - - Ada.Unchecked_Deallocation; - - -package body Packrat.Graphs is - - - procedure Free_Element_Array is new Ada.Unchecked_Deallocation - (Element_Array, Element_Array_Access); - - - - - - function "<" - (Left, Right : in Choice_Down) - return Boolean is - begin - return Left.From < Right.From or else - (Left.From = Right.From and Left.Choice < Right.Choice); - end "<"; - - - - - - procedure Adjust - (This : in out Elem_Wrapper) - is - New_Array : Element_Array_Access; - begin - if This.Data /= null then - New_Array := new Element_Array (This.Data'First .. This.Data'Last); - New_Array.all := This.Data.all; - This.Data := New_Array; - end if; - end Adjust; - - - procedure Finalize - (This : in out Elem_Wrapper) is - begin - if This.Data /= null then - Free_Element_Array (This.Data); - end if; - end Finalize; - - - function Wrap - (Data : in Element_Array) - return Elem_Wrapper - is - New_Array : Element_Array_Access := - new Element_Array (Data'First .. Data'Last); - begin - New_Array.all := Data; - return (Ada.Finalization.Controlled with Data => New_Array); - end Wrap; - - - - - - function Leaf - (New_Item : in Element_Array; - Start : in Positive; - Finish : in Natural) - return Node is - begin - return This : Node do - This.Kind := Leaf_Node; - This.Content := Wrap (New_Item); - This.Start := Start; - This.Finish := Finish; - end return; - end Leaf; - - - function Branch - (Label : in Label_Enum; - Start : in Positive; - Finish : in Natural) - return Node is - begin - return This : Node do - This.Kind := Branch_Node; - This.Ident := Label; - This.Start := Start; - This.Finish := Finish; - end return; - end Branch; - - - - - - function Is_Nothing - (This : in Node) - return Boolean is - begin - return This.Kind = Null_Node; - end Is_Nothing; - - - function Is_Leaf - (This : in Node) - return Boolean is - begin - return This.Kind = Leaf_Node; - end Is_Leaf; - - - function Is_Branch - (This : in Node) - return Boolean is - begin - return This.Kind = Branch_Node; - end Is_Branch; - - - - - - function Label - (This : in Node) - return Label_Enum is - begin - return This.Ident; - end Label; - - - function Elements - (This : in Node) - return Element_Array is - begin - return This.Content.Data.all; - end Elements; - - - function Start - (This : in Node) - return Positive is - begin - return This.Start; - end Start; - - - function Finish - (This : in Node) - return Natural is - begin - return This.Finish; - end Finish; - - - - - - function Is_Nothing - (Position : in Cursor) - return Boolean is - begin - return Position.My_Graph = null or else - Position.Index = 0 or else - Position.Index > Position.My_Graph.all.Node_List.Last_Index or else - Position.My_Graph.all.Node_List.Element (Position.Index).Kind = Null_Node; - end Is_Nothing; - - - - - - function Depth - (Position : in Cursor) - return Natural is - begin - return Natural (Position.Track.Length); - end Depth; - - - function Is_Node - (Position : in Cursor) - return Boolean is - begin - return not Is_Nothing (Position); - end Is_Node; - - - function Is_Root - (Position : in Cursor) - return Boolean is - begin - return Position.My_Graph /= null and then - Position.My_Graph.all.Root_List.Contains (Position.Index) and then - Depth (Position) = 0; - end Is_Root; - - - function Is_Branch - (Position : in Cursor) - return Boolean is - begin - return Position.My_Graph /= null and then - Position.Index /= 0 and then - Position.Index <= Position.My_Graph.all.Node_List.Last_Index and then - Position.My_Graph.all.Node_List.Element (Position.Index).Kind = Branch_Node; - end Is_Branch; - - - function Is_Leaf - (Position : in Cursor) - return Boolean is - begin - return Position.My_Graph /= null and then - Position.Index /= 0 and then - Position.Index <= Position.My_Graph.all.Node_List.Last_Index and then - Position.My_Graph.all.Node_List.Element (Position.Index).Kind = Leaf_Node; - end Is_Leaf; - - - function Label - (Position : in Cursor) - return Label_Enum is - begin - return Position.My_Graph.all.Node_List.Element (Position.Index).Ident; - end Label; - - - function Elements - (Position : in Cursor) - return Element_Array is - begin - return Position.My_Graph.all.Node_List.Element (Position.Index).Content.Data.all; - end Elements; - - - - - - function Start - (Position : in Cursor) - return Positive is - begin - return Position.My_Graph.all.Node_List.Element (Position.Index).Start; - end Start; - - - function Finish - (Position : in Cursor) - return Natural is - begin - return Position.My_Graph.all.Node_List.Element (Position.Index).Finish; - end Finish; - - - function Choices - (My_Graph : in Graph; - My_Index : in Node_Index) - return Natural is - begin - if not My_Graph.Choices.Contains (My_Index) then - return 0; - else - return My_Graph.Choices.Element (My_Index); - end if; - end Choices; - - - function Choices - (Position : in Cursor) - return Natural is - begin - if not Is_Branch (Position) then - return 0; - else - return Choices (Position.My_Graph.all, Position.Index); - end if; - end Choices; - - - - - - function Parent - (Position : in Cursor) - return Cursor is - begin - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - Result.Track := Position.Track; - if Natural (Position.Track.Length) = 0 then - Result.Index := 0; - else - Result.Index := Position.Track.Last_Element.From; - Result.Track.Delete_Last; - end if; - end return; - end Parent; - - - function Child_Count - (Position : in Cursor; - Choice : in Positive) - return Natural is - begin - return Natural (Position.My_Graph.all.Down_Edges.Element ((Position.Index, Choice)).Length); - end Child_Count; - - - function Child_Count - (Position : in Cursor) - return Natural - is - Choice_Count : Natural := Choices (Position); - begin - if Choice_Count = 0 then - return 0; - else - return Natural (Position.My_Graph.all.Down_Edges.Element - ((Position.Index, Choice_Count)).Length); - end if; - end Child_Count; - - - function All_Child_Count - (Position : in Cursor) - return Natural - is - Result : Natural := 0; - begin - for C in Integer range 1 .. Choices (Position) loop - Result := Result + Child_Count (Position, C); - end loop; - return Result; - end All_Child_Count; - - - function First_Child - (Position : in Cursor; - Choice : in Positive) - return Cursor is - begin - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - Result.Index := Position.My_Graph.all.Down_Edges.Element - ((Position.Index, Choice)).First_Element; - Result.Track := Position.Track; - Result.Track.Append ((Position.Index, Choice)); - end return; - end First_Child; - - - function Last_Child - (Position : in Cursor; - Choice : in Positive) - return Cursor is - begin - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - Result.Index := Position.My_Graph.all.Down_Edges.Element - ((Position.Index, Choice)).Last_Element; - Result.Track := Position.Track; - Result.Track.Append ((Position.Index, Choice)); - end return; - end Last_Child; - - - function First_Child - (Position : in Cursor) - return Cursor - is - Choice : Natural := Choices (Position); - begin - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - if Choice = 0 or Result.My_Graph = null then - Result.Index := 0; - else - Result.Index := Position.My_Graph.all.Down_Edges.Element - ((Position.Index, Choice)).First_Element; - end if; - Result.Track := Position.Track; - Result.Track.Append ((Position.Index, Choice)); - end return; - end First_Child; - - - function Last_Child - (Position : in Cursor) - return Cursor - is - Choice : Natural := Choices (Position); - begin - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - if Choice = 0 or Result.My_Graph = null then - Result.Index := 0; - else - Result.Index := Position.My_Graph.all.Down_Edges.Element - ((Position.Index, Choice)).Last_Element; - end if; - Result.Track := Position.Track; - Result.Track.Append ((Position.Index, Choice)); - end return; - end Last_Child; - - - function Next_Sibling - (Position : in Cursor) - return Cursor - is - Parent_Index : Extended_Node_Index; - Choice : Natural; - Sibling : Index_Vectors.Cursor; - begin - if Depth (Position) = 0 then - Parent_Index := 0; - Choice := 0; - else - Parent_Index := Position.Track.Last_Element.From; - Choice := Position.Track.Last_Element.Choice; - end if; - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - if Choice = 0 or Parent_Index = 0 or Result.My_Graph = null or Position.Index = 0 then - Result.Index := 0; - else - Sibling := Result.My_Graph.all.Down_Edges.Element - ((Parent_Index, Choice)).Find (Position.Index); - Index_Vectors.Next (Sibling); - if Index_Vectors.Has_Element (Sibling) then - Result.Index := Index_Vectors.Element (Sibling); - else - Result.Index := 0; - end if; - end if; - Result.Track := Position.Track; - end return; - end Next_Sibling; - - - function Prev_Sibling - (Position : in Cursor) - return Cursor - is - Parent_Index : Extended_Node_Index; - Choice : Natural; - Sibling : Index_Vectors.Cursor; - begin - if Depth (Position) = 0 then - Parent_Index := 0; - Choice := 0; - else - Parent_Index := Position.Track.Last_Element.From; - Choice := Position.Track.Last_Element.Choice; - end if; - return Result : Cursor do - Result.My_Graph := Position.My_Graph; - if Choice = 0 or Parent_Index = 0 or Result.My_Graph = null or Position.Index = 0 then - Result.Index := 0; - else - Sibling := Result.My_Graph.all.Down_Edges.Element - ((Parent_Index, Choice)).Find (Position.Index); - Index_Vectors.Previous (Sibling); - if Index_Vectors.Has_Element (Sibling) then - Result.Index := Index_Vectors.Element (Sibling); - else - Result.Index := 0; - end if; - end if; - Result.Track := Position.Track; - end return; - end Prev_Sibling; - - - - - - procedure Delete_Loose_Subgraph - (Container : in out Graph; - Index : in Node_Index) - is - use type Ada.Containers.Count_Type; - Number_Choices : Natural; - begin - if Container.Up_Edges.Contains (Index) and then - Container.Up_Edges.Reference (Index).Length > 0 - then - -- If this subgraph is still connected to the rest of the graph, - -- then we do nothing. - return; - end if; - - if Container.Choices.Contains (Index) then - Number_Choices := Container.Choices.Element (Index); - else - Number_Choices := 0; - end if; - - for C in reverse Integer range 1 .. Number_Choices loop - declare - Edges : Edge_Down_Maps.Reference_Type := - Container.Down_Edges.Reference ((Index, C)); - begin - for I in reverse Integer range 1 .. Edges.Last_Index loop - declare - Elem : Node_Index := Edges.Element.Element (I); - begin - Container.Delete_Up_Edge (Elem, Index); - Container.Delete_Loose_Subgraph (Elem); - end; - end loop; - end; - Container.Delete_Down_Edges (Index, C); - end loop; - - Container.Node_List.Reference (Index).Kind := Null_Node; - if Index < Container.Add_Place then - Container.Add_Place := Index; - end if; - while Container.Node_List.Length > 0 and then - Container.Node_List.Last_Element.Kind = Null_Node - loop - Container.Node_List.Delete_Last; - end loop; - - if Container.Root_List.Contains (Index) then - Container.Root_List.Delete (Container.Root_List.Reverse_Find_Index (Index)); - end if; - end Delete_Loose_Subgraph; - - - procedure Delete_Up_Edge - (Container : in out Graph; - Current, Parent : in Node_Index) - is - Index_List : Edge_Up_Maps.Reference_Type := - Container.Up_Edges.Reference (Current); - Place : Natural := Index_List.Reverse_Find_Index (Parent); - begin - Index_List.Delete (Place); - if Index_List.Is_Empty then - Container.Up_Edges.Delete (Current); - end if; - end Delete_Up_Edge; - - - procedure Delete_Down_Edges - (Container : in out Graph; - From : in Node_Index; - Choice : in Positive) - is - Number_Choices : Choice_Maps.Reference_Type := Container.Choices.Reference (From); - begin - for C in Integer range Choice + 1 .. Number_Choices loop - Container.Down_Edges.Replace - ((From, C - 1), - Container.Down_Edges.Element ((From, C))); - end loop; - Container.Down_Edges.Delete ((From, Number_Choices)); - Number_Choices := Number_Choices - 1; - if Number_Choices < 1 then - Container.Choices.Delete (From); - end if; - end Delete_Down_Edges; - - - procedure Delete_Children - (Position : in out Cursor; - Choice : in Positive) - is - use type Ada.Containers.Count_Type; - Index_List : Edge_Down_Maps.Reference_Type := - Position.My_Graph.all.Down_Edges.Reference ((Position.Index, Choice)); - begin - for I in reverse Integer range Index_List.First_Index .. Index_List.Last_Index loop - declare - Elem : Node_Index := Index_List.Element.Element (I); - begin - Position.My_Graph.all.Delete_Up_Edge (Elem, Position.Index); - Position.My_Graph.all.Delete_Loose_Subgraph (Elem); - end; - end loop; - Position.My_Graph.all.Delete_Down_Edges (Position.Index, Choice); - while Position.My_Graph.all.Node_List.Length > 0 and then - Position.My_Graph.all.Node_List.Last_Element.Kind = Null_Node - loop - Position.My_Graph.all.Node_List.Delete_Last; - end loop; - end Delete_Children; - - - procedure Delete_Children - (Position : in out Cursor) - is - Choice : Natural := Choices (Position); - begin - if Choice > 0 then - Delete_Children (Position, Choice); - end if; - end Delete_Children; - - - procedure Delete_All_Children - (Position : in out Cursor) is - begin - for I in reverse Integer range 1 .. Choices (Position) loop - Delete_Children (Position, I); - end loop; - end Delete_All_Children; - - - - - - function Equal_Subgraph - (Left_Graph, Right_Graph : in Graph; - Left_Index, Right_Index : in Node_Index) - return Boolean - is - use type Ada.Containers.Count_Type; - begin - if Left_Graph.Node_List.Element (Left_Index) /= - Right_Graph.Node_List.Element (Right_Index) - then - return False; - end if; - - if Choices (Left_Graph, Left_Index) /= - Choices (Right_Graph, Right_Index) - then - return False; - end if; - - for C in Integer range 1 .. Choices (Left_Graph, Left_Index) loop - declare - Left_List : Edge_Down_Maps.Constant_Reference_Type := - Left_Graph.Down_Edges.Constant_Reference ((Left_Index, C)); - Right_List : Edge_Down_Maps.Constant_Reference_Type := - Right_Graph.Down_Edges.Constant_Reference ((Right_Index, C)); - begin - if Left_List.Length /= Right_List.Length then - return False; - end if; - for I in Integer range 1 .. Left_List.Last_Index loop - if not Equal_Subgraph - (Left_Graph, - Right_Graph, - Left_List.Element.Element (I), - Right_List.Element.Element (I)) - then - return False; - end if; - end loop; - end; - end loop; - - return True; - end Equal_Subgraph; - - - function Equal_Subgraph - (Left, Right : in Cursor) - return Boolean is - begin - return Equal_Subgraph - (Left.My_Graph.all, - Right.My_Graph.all, - Left.Index, - Right.Index); - end Equal_Subgraph; - - - - - - function Node_Count - (Container : in Graph; - Root_List : in Index_Vectors.Vector) - return Natural - is - Result : Natural := 0; - Current_Vector : Index_Vectors.Vector := Root_List; - New_Vector : Index_Vectors.Vector := Index_Vectors.Empty_Vector; - begin - while Natural (Current_Vector.Length) > 0 loop - Result := Result + Natural (Current_Vector.Length); - for N of Current_Vector loop - if Is_Branch (Container.Node_List.Element (N)) and - Container.Choices.Contains (N) - then - for C in Integer range 1 .. Container.Choices.Element (N) loop - New_Vector.Append (Container.Down_Edges.Element ((N, C))); - end loop; - end if; - end loop; - Current_Vector := New_Vector; - New_Vector.Clear; - end loop; - return Result; - end Node_Count; - - - function Subgraph_Node_Count - (Position : in Cursor) - return Natural - is - use type Index_Vectors.Vector; - begin - return Node_Count - (Position.My_Graph.all, - Index_Vectors.Empty_Vector & Position.Index); - end Subgraph_Node_Count; - - - function Find_In_Subgraph - (Position : in Cursor; - Item : in Element_Array) - return Cursor is - begin - return This : Cursor; - end Find_In_Subgraph; - - - - - - function Contains - (Container : in Graph; - Position : in Cursor) - return Boolean is - begin - return Position.My_Graph = Container'Unrestricted_Access and then - Position.Index < Container.Node_List.Last_Index and then - Position.Index > 0 and then - Container.Node_List.Element (Position.Index).Kind /= Null_Node; - end Contains; - - - - - function Singleton - (Input : in Node) - return Graph is - begin - return Result : Graph do - Result.Root_List := Index_Vectors.Empty_Vector; - Result.Root_List.Append (1); - Result.Node_List := Node_Vectors.Empty_Vector; - Result.Node_List.Append (Input); - Result.Add_Place := 2; - Result.Choices := Choice_Maps.Empty_Map; - Result.Down_Edges := Edge_Down_Maps.Empty_Map; - Result.Up_Edges := Edge_Up_Maps.Empty_Map; - end return; - end Singleton; - - - function Node_At - (Container : in Graph; - Position : in Cursor) - return Node_Reference is - begin - return (Data => No_Node'Unrestricted_Access); - end Node_At; - - - - - - function Is_Empty - (Container : in Graph) - return Boolean is - begin - return Container.Root_List.Is_Empty; - end Is_Empty; - - - function Is_Ambiguous - (Container : in Graph) - return Boolean is - begin - if Natural (Container.Root_List.Length) > 1 then - return True; - end if; - for N in Node_Index range 1 .. Container.Node_List.Last_Index loop - if Container.Node_List.Element (N).Kind = Branch_Node and then - Container.Choices.Contains (N) and then - Container.Choices.Element (N) > 1 - then - return True; - end if; - end loop; - return False; - end Is_Ambiguous; - - - function Node_Count - (Container : in Graph) - return Natural is - begin - return Node_Count (Container, Container.Root_List); - end Node_Count; - - - - - - function Root_Count - (Container : in Graph) - return Natural is - begin - return Natural (Container.Root_List.Length); - end Root_Count; - - - function Root - (Container : in Graph; - Index : in Positive) - return Cursor is - begin - return Result : Cursor do - Result.My_Graph := Container'Unrestricted_Access; - Result.Index := Container.Root_List.Element (Index); - Result.Track := Choice_Down_Vectors.Empty_Vector; - end return; - end Root; - - - - - - procedure Add_Nodes - (Container : in out Graph; - Addition : in Node_Vectors.Vector; - Mapping : out Index_Maps.Map) is - begin - Mapping := Index_Maps.Empty_Map; - for C in Addition.Iterate loop - Mapping.Insert (Node_Vectors.To_Index (C), Container.Add_Place); - if Container.Add_Place > Container.Node_List.Last_Index then - Container.Node_List.Append (Node_Vectors.Element (C)); - else - Container.Node_List.Replace_Element (Container.Add_Place, Node_Vectors.Element (C)); - end if; - while Container.Add_Place <= Container.Node_List.Last_Index and then - not Is_Nothing (Container.Node_List.Element (Container.Add_Place)) - loop - Container.Add_Place := Container.Add_Place + 1; - end loop; - end loop; - end Add_Nodes; - - - procedure Add_Edges - (Container : in out Graph; - Addition : in Graph; - Mapping : in Index_Maps.Map) - is - Targets : Index_Vectors.Vector := Index_Vectors.Empty_Vector; - begin - -- Up edges - for E in Addition.Up_Edges.Iterate loop - Targets.Clear; - for T of Edge_Up_Maps.Element (E) loop - Targets.Append (Mapping.Element (T)); - end loop; - Container.Up_Edges.Insert - (Mapping.Element (Edge_Up_Maps.Key (E)), Targets); - end loop; - - -- Down edges - for E in Addition.Down_Edges.Iterate loop - Targets.Clear; - for T of Edge_Down_Maps.Element (E) loop - Targets.Append (Mapping.Element (T)); - end loop; - Container.Down_Edges.Insert - ((Mapping.Element (Edge_Down_Maps.Key (E).From), Edge_Down_Maps.Key (E).Choice), - Targets); - end loop; - - -- Choices - for C in Addition.Choices.Iterate loop - Container.Choices.Insert - (Mapping.Element (Choice_Maps.Key (C)), Choice_Maps.Element (C)); - end loop; - end Add_Edges; - - - procedure Append - (Container : in out Graph; - Addition : in Graph) - is - Mapping : Index_Maps.Map; - begin - -- Add the nodes and edges from the addition to the graph, - -- making sure to handle the conversion of the index each node - -- is stored at. If index conversion wasn't required this bit would - -- be much simpler. - Add_Nodes (Container, Addition.Node_List, Mapping); - Add_Edges (Container, Addition, Mapping); - - -- Append the root list of the addition to the graph - for R of Addition.Root_List loop - Container.Root_List.Append (Mapping.Element (R)); - end loop; - end Append; - - - procedure Prepend - (Container : in out Graph; - Addition : in Graph) - is - Mapping : Index_Maps.Map; - Converted_Roots : Index_Vectors.Vector := Index_Vectors.Empty_Vector; - begin - -- Add the nodes and edges from the addition to the graph, - -- making sure to handle the conversion of the index each node - -- is stored at. If index conversion wasn't required this bit would - -- be much simpler. - Add_Nodes (Container, Addition.Node_List, Mapping); - Add_Edges (Container, Addition, Mapping); - - -- Prepend the root list of the addition to the graph - for R of Addition.Root_List loop - Converted_Roots.Append (Mapping.Element (R)); - end loop; - Container.Root_List.Prepend (Converted_Roots); - end Prepend; - - - procedure Attach_Choice - (Container : in out Graph; - Position : in Cursor; - Addition : in Graph) is - begin - null; - end Attach_Choice; - - - - - - procedure Clear - (Container : in out Graph) is - begin - Container.Root_List.Clear; - Container.Node_List.Clear; - Container.Add_Place := 1; - Container.Choices.Clear; - Container.Down_Edges.Clear; - Container.Up_Edges.Clear; - end Clear; - - - procedure Delete_Position - (Container : in out Graph; - Position : in out Cursor) - is - use type Ada.Containers.Count_Type; - begin - if Position.Track.Length > 0 then - Delete_Up_Edge (Container, Position.Index, Position.Track.Last_Element.From); - declare - Last : Choice_Down := - Position.Track.Last_Element; - Ref : Edge_Down_Maps.Reference_Type := - Container.Down_Edges.Reference (Last); - Number_Choices : Choice_Maps.Reference_Type := - Container.Choices.Reference (Last.From); - begin - Ref.Delete (Ref.Find_Index (Position.Index)); - if Ref.Length = 0 then - for C in Integer range Last.Choice + 1 .. Number_Choices loop - Container.Down_Edges.Replace - ((Last.From, C - 1), - Container.Down_Edges.Element ((Last.From, C))); - end loop; - Container.Down_Edges.Delete ((Last.From, Number_Choices)); - Number_Choices := Number_Choices - 1; - if Number_Choices < 1 then - Container.Choices.Delete (Last.From); - end if; - end if; - end; - end if; - Delete_Loose_Subgraph (Container, Position.Index); - while Position.My_Graph.all.Node_List.Length > 0 and then - Position.My_Graph.all.Node_List.Last_Element.Kind = Null_Node - loop - Position.My_Graph.all.Node_List.Delete_Last; - end loop; - end Delete_Position; - - - - - - function Find - (Container : in Graph; - Item : in Element_Array) - return Cursor is - begin - return This : Cursor; - end Find; - - - - - - function Default_Choices - (Container : in Graph; - Position : in Cursor) - return Natural is - begin - if Is_Nothing (Position) then - return Container.Root_Count; - else - return Choices (Position); - end if; - end Default_Choices; - - - function Accept_All - (Position : in Cursor) - return Boolean is - begin - return not Is_Nothing (Position); - end Accept_All; - - - - - - function Iterate - (Container : in Graph; - Start_At : in Cursor := No_Position; - Choose : in Choosing_Function := Default_Choices'Access; - Filter : in Filter_Function := Accept_All'Access) - return Graph_Iterators.Reversible_Iterator'Class is - begin - return This : Reversible_Iterator do - This.My_Graph := Container'Unrestricted_Access; - This.Start_Pos := Start_At; - This.Rule := Specific_Branch; - This.Choose_Func := Choose; - This.Filter_Func := Filter; - end return; - end Iterate; - - - function Iterate_All - (Container : in Graph; - Start_At : in Cursor := No_Position; - Filter : in Filter_Function := Accept_All'Access) - return Graph_Iterators.Reversible_Iterator'Class is - begin - return This : Reversible_Iterator do - This.My_Graph := Container'Unrestricted_Access; - This.Start_Pos := Start_At; - This.Rule := All_Nodes; - This.Choose_Func := null; - This.Filter_Func := Filter; - end return; - end Iterate_All; - - - - - - function First - (Object : in Reversible_Iterator) - return Cursor is - begin - if Object.My_Graph = null or else Object.My_Graph.all.Is_Empty then - return No_Position; - elsif Is_Nothing (Object.Start_Pos) then - if Object.Rule = All_Nodes then - return Object.My_Graph.all.Root (1); - else - return Object.My_Graph.all.Root - (Object.Choose_Func (Object.My_Graph.all, No_Position)); - end if; - else - return Object.Start_Pos; - end if; - end First; - - - function Next - (Object : in Reversible_Iterator; - Place : in Cursor) - return Cursor is - begin - if Object.My_Graph = null or else - Object.My_Graph.all.Is_Empty or else - Is_Nothing (Place) - then - return No_Position; - end if; -- elsif - return No_Position; - end Next; - - - function Last - (Object : in Reversible_Iterator) - return Cursor is - begin - return No_Position; - end Last; - - - function Previous - (Object : in Reversible_Iterator; - Place : in Cursor) - return Cursor is - begin - return No_Position; - end Previous; - - -end Packrat.Graphs; - - diff --git a/src/packrat-graphs.ads b/src/packrat-graphs.ads deleted file mode 100644 index 6bceaaf..0000000 --- a/src/packrat-graphs.ads +++ /dev/null @@ -1,657 +0,0 @@ - - -with - - Ada.Iterator_Interfaces; - -private with - - Ada.Containers.Ordered_Maps, - Ada.Containers.Vectors; - - -generic - type Label_Enum is (<>); - type Element is private; - type Element_Array is array (Positive range <>) of Element; -package Packrat.Graphs is - - - type Node is private; - - type Node_Reference (Data : not null access Node) is limited null record - with Implicit_Dereference => Data; - - type Cursor is private; - - type Graph is tagged private - with Default_Iterator => Iterate, - Iterator_Element => Node_Reference, - Variable_Indexing => Node_At; - - - - - No_Position : constant Cursor; - - Empty_Graph : constant Graph; - - - - - function Leaf - (New_Item : in Element_Array; - Start : in Positive; - Finish : in Natural) - return Node - with Pre => - Finish + 1 >= Start, - Post => - Is_Leaf (Leaf'Result); - - function Branch - (Label : in Label_Enum; - Start : in Positive; - Finish : in Natural) - return Node - with Pre => - Finish + 1 >= Start, - Post => - Is_Branch (Branch'Result); - - - - - function Is_Leaf - (This : in Node) - return Boolean; - - function Is_Branch - (This : in Node) - return Boolean; - - - - - function Label - (This : in Node) - return Label_Enum - with Pre => - Is_Branch (This); - - function Elements - (This : in Node) - return Element_Array - with Pre => - Is_Leaf (This); - - function Start - (This : in Node) - return Positive; - - function Finish - (This : in Node) - return Natural; - - - - - function Is_Nothing - (Position : in Cursor) - return Boolean; - - - - - function Depth - (Position : in Cursor) - return Natural; - - function Is_Node - (Position : in Cursor) - return Boolean - with Post => - (if Is_Node'Result then not Is_Nothing (Position)); - - function Is_Root - (Position : in Cursor) - return Boolean - with Post => - (if Is_Root'Result then - not Is_Nothing (Position) and - Is_Nothing (Parent (Position)) and - Depth (Position) = 0); - - function Is_Branch - (Position : in Cursor) - return Boolean - with Post => - (if Is_Branch'Result then not Is_Nothing (Position)); - - function Is_Leaf - (Position : in Cursor) - return Boolean - with Post => - (if Is_Leaf'Result then not Is_Nothing (Position)); - - - - - function Label - (Position : in Cursor) - return Label_Enum - with Pre => - Is_Branch (Position); - - function Elements - (Position : in Cursor) - return Element_Array - with Pre => - Is_Leaf (Position); - - function Start - (Position : in Cursor) - return Positive - with Pre => - not Is_Nothing (Position); - - function Finish - (Position : in Cursor) - return Natural - with Pre => - not Is_Nothing (Position); - - function Choices - (Position : in Cursor) - return Natural; - - - - - function Parent - (Position : in Cursor) - return Cursor; - - function Child_Count - (Position : in Cursor; - Choice : in Positive) - return Natural - with Pre => - Choice <= Choices (Position); - - function Child_Count - (Position : in Cursor) - return Natural; - - function All_Child_Count - (Position : in Cursor) - return Natural; - - function First_Child - (Position : in Cursor; - Choice : in Positive) - return Cursor - with Pre => - Choice <= Choices (Position), - Post => - Parent (First_Child'Result) = Position; - - function Last_Child - (Position : in Cursor; - Choice : in Positive) - return Cursor - with Pre => - Choice <= Choices (Position), - Post => - Parent (Last_Child'Result) = Position; - - function First_Child - (Position : in Cursor) - return Cursor - with Post => - Parent (First_Child'Result) = Position; - - function Last_Child - (Position : in Cursor) - return Cursor - with Post => - Parent (Last_Child'Result) = Position; - - function Next_Sibling - (Position : in Cursor) - return Cursor - with Post => - Parent (Next_Sibling'Result) = Parent (Position); - - function Prev_Sibling - (Position : in Cursor) - return Cursor - with Post => - Parent (Prev_Sibling'Result) = Parent (Position); - - procedure Delete_Children - (Position : in out Cursor; - Choice : in Positive) - with Pre => - Choice <= Choices (Position), - Post => - Child_Count (Position, Choice) = 0; - - procedure Delete_Children - (Position : in out Cursor) - with Post => - Child_Count (Position) = 0; - - procedure Delete_All_Children - (Position : in out Cursor) - with Post => - All_Child_Count (Position) = 0; - - - - - function Equal_Subgraph - (Left, Right : in Cursor) - return Boolean - with Pre => - Is_Node (Left) and Is_Node (Right); - - function Subgraph_Node_Count - (Position : in Cursor) - return Natural; - - function Find_In_Subgraph - (Position : in Cursor; - Item : in Element_Array) - return Cursor - with Post => - Is_Nothing (Find_In_Subgraph'Result) or - Is_Leaf (Find_In_Subgraph'Result); - - - - - function Contains - (Container : in Graph; - Position : in Cursor) - return Boolean - with Post => - (if Contains'Result then not Is_Nothing (Position)); - - - - - function Singleton - (Input : in Node) - return Graph - with Post => - Singleton'Result.Node_Count = 1; - - function Node_At - (Container : in Graph; - Position : in Cursor) - return Node_Reference - with Pre => - Contains (Container, Position); - - - - - function Is_Empty - (Container : in Graph) - return Boolean - with Post => - (if Is_Empty'Result then Container.Node_Count = 0 else Container.Node_Count /= 0); - - function Is_Ambiguous - (Container : in Graph) - return Boolean; - - function Node_Count - (Container : in Graph) - return Natural; - - - - - function Root_Count - (Container : in Graph) - return Natural - with Post => - (if Container.Is_Empty then Root_Count'Result = 0 else Root_Count'Result > 0); - - function Root - (Container : in Graph; - Index : in Positive) - return Cursor - with Pre => - Index <= Container.Root_Count; - - - - - procedure Append - (Container : in out Graph; - Addition : in Graph) - with Pre => - Container.Is_Empty or else Addition.Is_Empty or else - Finish (Container.Root (Container.Root_Count)) < Start (Addition.Root (1)); - - procedure Prepend - (Container : in out Graph; - Addition : in Graph) - with Pre => - Container.Is_Empty or else Addition.Is_Empty or else - Start (Container.Root (1)) > Finish (Addition.Root (Addition.Root_Count)); - - procedure Attach_Choice - (Container : in out Graph; - Position : in Cursor; - Addition : in Graph) - with Pre => - Container.Contains (Position) and Is_Branch (Position) and - (Addition.Is_Empty or else - (Start (Position) <= Start (Addition.Root (1)) and - Finish (Position) >= Finish (Addition.Root (Addition.Root_Count)))); - - - - - procedure Clear - (Container : in out Graph) - with Post => - Container.Is_Empty; - - procedure Delete_Position - (Container : in out Graph; - Position : in out Cursor) - with Pre'Class => - Container.Contains (Position), - Post'Class => - not Container.Contains (Position); - - - - - function Find - (Container : in Graph; - Item : in Element_Array) - return Cursor - with Post => - Is_Leaf (Find'Result) or - Is_Nothing (Find'Result); - - - - - package Graph_Iterators is - new Ada.Iterator_Interfaces (Cursor, Is_Node); - - -- Note that if the given Cursor doesn't point to any position, - -- then the function should assume that the choice is of what root to - -- select and return that value. - type Choosing_Function is access function - (Container : in Graph; - Position : in Cursor) - return Natural; - - -- This function returns True if a Node pointed to by a Cursor should - -- be returned, and False if it should be ignored. An example of a - -- filter that will probably see a decent amount of use would be Is_Leaf. - type Filter_Function is access function - (Position : in Cursor) - return Boolean; - - - - - function Default_Choices - (Container : in Graph; - Position : in Cursor) - return Natural; - - function Accept_All - (Position : in Cursor) - return Boolean; - - - - - function Iterate - (Container : in Graph; - Start_At : in Cursor := No_Position; - Choose : in Choosing_Function := Default_Choices'Access; - Filter : in Filter_Function := Accept_All'Access) - return Graph_Iterators.Reversible_Iterator'Class - with Pre => - Container.Contains (Start_At) or Is_Nothing (Start_At); - - function Iterate_All - (Container : in Graph; - Start_At : in Cursor := No_Position; - Filter : in Filter_Function := Accept_All'Access) - return Graph_Iterators.Reversible_Iterator'Class - with Pre => - Container.Contains (Start_At) or Is_Nothing (Start_At); - - - - -private - - - subtype Node_Index is Positive; - subtype Extended_Node_Index is Natural; - - - - - function Choices - (My_Graph : in Graph; - My_Index : in Node_Index) - return Natural - with Pre => - My_Index <= My_Graph.Node_List.Last_Index; - - - procedure Delete_Loose_Subgraph - (Container : in out Graph; - Index : in Node_Index) - with Pre => - Index <= Container.Node_List.Last_Index and then - Container.Node_List.Element (Index).Kind /= Null_Node; - - procedure Delete_Up_Edge - (Container : in out Graph; - Current, Parent : in Node_Index) - with Pre => - Container.Up_Edges.Contains (Current) and then - Container.Up_Edges.Reference (Current).Contains (Parent); - - procedure Delete_Down_Edges - (Container : in out Graph; - From : in Node_Index; - Choice : in Positive) - with Pre => - Container.Choices.Contains (From) and then - Container.Choices.Element (From) > 0 and then - Container.Down_Edges.Contains ((From, Choice)), - Post => - not Container.Down_Edges.Contains ((From, Choice)); - - - function Equal_Subgraph - (Left_Graph, Right_Graph : in Graph; - Left_Index, Right_Index : in Node_Index) - return Boolean - with Pre => - Left_Index <= Left_Graph.Node_List.Last_Index and - Right_Index <= Right_Graph.Node_List.Last_Index; - - - - - package Index_Vectors is new Ada.Containers.Vectors - (Index_Type => Positive, - Element_Type => Node_Index); - - package Index_Maps is new Ada.Containers.Ordered_Maps - (Key_Type => Node_Index, - Element_Type => Node_Index); - - - - - function Node_Count - (Container : in Graph; - Root_List : in Index_Vectors.Vector) - return Natural; - - - - - type Choice_Down is record - From : Extended_Node_Index; - Choice : Natural; - end record; - - function "<" - (Left, Right : in Choice_Down) - return Boolean; - - package Choice_Down_Vectors is new Ada.Containers.Vectors - (Index_Type => Positive, - Element_Type => Choice_Down); - - - - - package Choice_Maps is new Ada.Containers.Ordered_Maps - (Key_Type => Node_Index, - Element_Type => Natural); - - package Edge_Down_Maps is new Ada.Containers.Ordered_Maps - (Key_Type => Choice_Down, - Element_Type => Index_Vectors.Vector, - "=" => Index_Vectors."="); - - package Edge_Up_Maps is new Ada.Containers.Ordered_Maps - (Key_Type => Node_Index, - Element_Type => Index_Vectors.Vector, - "=" => Index_Vectors."="); - - - - - type Element_Array_Access is access Element_Array; - - type Elem_Wrapper is new Ada.Finalization.Controlled with record - Data : Element_Array_Access; - end record; - - overriding procedure Adjust - (This : in out Elem_Wrapper); - - overriding procedure Finalize - (This : in out Elem_Wrapper); - - function Wrap - (Data : in Element_Array) - return Elem_Wrapper; - - Empty_Wrapper : constant Elem_Wrapper := - (Ada.Finalization.Controlled with Data => null); - - type Node_Kind is (Null_Node, Branch_Node, Leaf_Node); - - type Node is record - Kind : Node_Kind; - Ident : Label_Enum; - Content : Elem_Wrapper; - Start : Positive; - Finish : Natural; - end record; - - package Node_Vectors is new Ada.Containers.Vectors - (Index_Type => Node_Index, - Element_Type => Node); - - - - - type Cursor is record - My_Graph : access Graph; - Index : Extended_Node_Index; - Track : Choice_Down_Vectors.Vector; - end record; - - - - - type Graph is tagged record - Root_List : Index_Vectors.Vector; - Node_List : Node_Vectors.Vector; - Add_Place : Node_Index; - Choices : Choice_Maps.Map; - Down_Edges : Edge_Down_Maps.Map; - Up_Edges : Edge_Up_Maps.Map; - end record; - - - - - No_Node : constant Node := - (Kind => Null_Node, - Ident => Label_Enum'First, - Content => Empty_Wrapper, - Start => 1, - Finish => 0); - - No_Position : constant Cursor := - (My_Graph => null, - Index => 0, - Track => Choice_Down_Vectors.Empty_Vector); - - Empty_Graph : constant Graph := - (Root_List => Index_Vectors.Empty_Vector, - Node_List => Node_Vectors.Empty_Vector, - Add_Place => 1, - Choices => Choice_Maps.Empty_Map, - Down_Edges => Edge_Down_Maps.Empty_Map, - Up_Edges => Edge_Up_Maps.Empty_Map); - - - - - type Iterate_Kind is (Specific_Branch, All_Nodes); - - type Reversible_Iterator is new Graph_Iterators.Reversible_Iterator with record - My_Graph : access Graph; - Start_Pos : Cursor; - Rule : Iterate_Kind; - Choose_Func : Choosing_Function; - Filter_Func : Filter_Function; - end record; - - overriding function First - (Object : in Reversible_Iterator) - return Cursor; - - overriding function Next - (Object : in Reversible_Iterator; - Place : in Cursor) - return Cursor; - - overriding function Last - (Object : in Reversible_Iterator) - return Cursor; - - overriding function Previous - (Object : in Reversible_Iterator; - Place : in Cursor) - return Cursor; - - -end Packrat.Graphs; - - diff --git a/src/packrat-parse_graphs.ads b/src/packrat-parse_graphs.ads index 0a3660e..d9cde0b 100644 --- a/src/packrat-parse_graphs.ads +++ b/src/packrat-parse_graphs.ads @@ -180,6 +180,15 @@ package Packrat.Parse_Graphs is + -- Other things needed here... + -- Equal_Subgraph? (in Directed_Graph lib) + -- Is_Ambiguous? + -- Iterate_Short, Iterate_Long, Iterate_By + -- Choosing and Filtering functions for Iterate_By + + + + -- Since this package sets the Nodes, Edges, and Labels of the Graphs -- to be specific types, it cannot be a child package of Directed_Graphs. -- Yet, it still is an extension of that package. To make it all work |