From cc1795dce90c4a498ddfed155c1f3a6f83a50f1d Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Thu, 3 Dec 2020 22:39:00 +1100 Subject: Parser constraint error bugs fixed --- src/packrat-parsers.adb | 95 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 30 deletions(-) (limited to 'src/packrat-parsers.adb') diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb index 6672dc3..f639195 100644 --- a/src/packrat-parsers.adb +++ b/src/packrat-parsers.adb @@ -72,6 +72,33 @@ package body Packrat.Parsers is + function Element + (Hold : in Elem_Holds.Holder) + return Traits.Element_Array is + begin + if Hold.Is_Empty then + return Value : Traits.Element_Array (1 .. 0); + else + return Hold.Element; + end if; + end Element; + + + function Element + (Hold : in Tok_Holds.Holder) + return Graphs.Finished_Token_Array is + begin + if Hold.Is_Empty then + return Value : Graphs.Finished_Token_Array (1 .. 0); + else + return Hold.Element; + end if; + end Element; + + + + + function To_Key (Start : in Positive; Func : access function @@ -125,7 +152,7 @@ package body Packrat.Parsers is end if; Result := Actual (Context); if Result.Status = Needs_More or Result.Status = Optional_More then - Context.Needs_More.Insert (My_Key.Start); + Context.Needs_More.Include (My_Key.Start); end if; if Context.Memotable.Contains (My_Key) then Context.Memotable.Replace (My_Key, Result); @@ -281,10 +308,10 @@ package body Packrat.Parsers is Temp := Next (Input, Context, R.Finish + 1); Adjust.Clear; for N of Temp.Results loop - Adjust.Insert + Adjust.Include ((Finish => N.Finish, - Value => Elem_Holds.To_Holder (R.Value.Element & N.Value.Element), - Tokens => Tok_Holds.To_Holder (R.Tokens.Element & N.Tokens.Element))); + Value => Elem_Holds.To_Holder (Element (R.Value) & Element (N.Value)), + Tokens => Tok_Holds.To_Holder (Element (R.Tokens) & Element (N.Tokens)))); end loop; Temp.Results := Adjust; Merge (Salt, Temp); @@ -366,7 +393,9 @@ package body Packrat.Parsers is Index : Positive := 1; begin for R of Root_Result.Results loop - Length := Length + Integer (R.Tokens.Element'Length); + if not R.Tokens.Is_Empty then + Length := Length + Integer (Element (R.Tokens)'Length); + end if; end loop; if Length = 0 then return Graphs.Empty_Graph; @@ -375,7 +404,7 @@ package body Packrat.Parsers is Root_Elems : Graphs.Finished_Token_Array (1 .. Length); begin for R of Root_Result.Results loop - for T of R.Tokens.Element loop + for T of Element (R.Tokens) loop Root_Elems (Index) := T; Index := Index + 1; end loop; @@ -399,12 +428,12 @@ package body Packrat.Parsers is Real_Input : Traits.Element_Array := (if Context.Pass_Forward.Is_Empty then Slide (Input, Context.Current_Position) - else Context.Pass_Forward.Element & Input); + else Element (Context.Pass_Forward) & Input); Root_Result : Combinator_Result := Root (Real_Input, Context, Context.Global_Start); begin if Root_Result.Status = Failure then - raise Parser_Error; + raise Parser_Error with -Context.Error_String; end if; if Input'Length = 0 then Result := Finish_Root (Root_Result, Context); @@ -434,12 +463,12 @@ package body Packrat.Parsers is Real_Input : Traits.Element_Array := (if Context.Pass_Forward.Is_Empty then Slide (Input, Context.Current_Position) - else Context.Pass_Forward.Element & Input); + else Element (Context.Pass_Forward) & Input); Root_Result : Combinator_Result := Root (Real_Input, Context, Context.Global_Start); begin if Root_Result.Status /= Success then - raise Parser_Error; + raise Parser_Error with -Context.Error_String; end if; return Finish_Root (Root_Result, Context); end; @@ -484,21 +513,24 @@ package body Packrat.Parsers is Processed : Result_Sets.Set; begin if Salt.Status = Failure then - raise Parser_Error with Packrat.Errors.Encode - (Traits.Label_Enum'Image (Label), Start); + Ada.Strings.Unbounded.Append + (Context.Error_String, + Packrat.Errors.Encode (Traits.Label_Enum'Image (Label), Start)); + else + Context.Error_String := +""; end if; for R of Salt.Results loop Current := - (Token => Traits.Tokens.Create (Label, Start, R.Value.Element), + (Token => Traits.Tokens.Create (Label, Start, Element (R.Value)), Finish => R.Finish); if Salt.Status = Success then - if R.Tokens.Element'Length > 0 then - Context.Result_So_Far.Connect (Current, R.Tokens.Element); + if not R.Tokens.Is_Empty then + Context.Result_So_Far.Connect (Current, Element (R.Tokens)); else Context.Result_So_Far.Include (Current.Token); end if; end if; - Processed.Insert + Processed.Include ((Finish => R.Finish, Value => Elem_Holds.Empty_Holder, Tokens => Tok_Holds.To_Holder ((1 => Current)))); @@ -526,11 +558,14 @@ package body Packrat.Parsers is Processed : Result_Sets.Set; begin if Salt.Status = Failure then - raise Parser_Error with Packrat.Errors.Encode - (Traits.Label_Enum'Image (Label), Start); + Ada.Strings.Unbounded.Append + (Context.Error_String, + Packrat.Errors.Encode (Traits.Label_Enum'Image (Label), Start)); + else + Context.Error_String := +""; end if; for R of Salt.Results loop - Processed.Insert + Processed.Include ((Finish => R.Finish, Value => Elem_Holds.Empty_Holder, Tokens => Tok_Holds.Empty_Holder)); @@ -725,7 +760,7 @@ package body Packrat.Parsers is Adjust.Clear; for R of Temp.Results loop if R.Finish = Input'Last or else not Test (Input (R.Finish + 1)) then - Adjust.Insert (R); + Adjust.Include (R); end if; end loop; Temp.Results.Assign (Adjust); @@ -787,7 +822,7 @@ package body Packrat.Parsers is if Start <= Input'Last and then Test (Input (Start)) then Part.Finish := Start; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := Success; end if; return Salt; @@ -814,7 +849,7 @@ package body Packrat.Parsers is if Start <= Input'Last and then Test (Change (Input (Start))) then Part.Finish := Start; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := Success; end if; return Salt; @@ -842,7 +877,7 @@ package body Packrat.Parsers is if Start <= Input'Last and then Input (Start) = Item then Part.Finish := Start; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := Success; end if; return Salt; @@ -870,7 +905,7 @@ package body Packrat.Parsers is if Start <= Input'Last and then Change (Input (Start)) = Item then Part.Finish := Start; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := Success; end if; return Salt; @@ -916,7 +951,7 @@ package body Packrat.Parsers is return Salt : Combinator_Result do Part.Finish := Start + My_Offset; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start + My_Offset)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := (if My_Offset < Items'Length - 1 then Needs_More else Success); end return; end Actual; @@ -953,7 +988,7 @@ package body Packrat.Parsers is return Salt : Combinator_Result do Part.Finish := Start + My_Offset; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start + My_Offset)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := (if My_Offset < Number - 1 then Needs_More else Success); end return; end Actual; @@ -986,7 +1021,7 @@ package body Packrat.Parsers is return Salt : Combinator_Result do Part.Finish := My_Finish; Part.Value := Elem_Holds.To_Holder (Input (Start .. My_Finish)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := (if My_Finish = Input'Last and Context.Allow_Incomplete then Optional_More else Success); end return; @@ -1020,7 +1055,7 @@ package body Packrat.Parsers is return Salt : Combinator_Result do Part.Finish := My_Finish; Part.Value := Elem_Holds.To_Holder (Input (Start .. My_Finish)); - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := (if My_Finish = Input'Last and Context.Allow_Incomplete then Optional_More else Success); end return; @@ -1044,7 +1079,7 @@ package body Packrat.Parsers is Salt : Combinator_Result; begin Part.Finish := Start - 1; - Salt.Results.Insert (Part); + Salt.Results.Include (Part); Salt.Status := Success; return Salt; end Empty; @@ -1061,7 +1096,7 @@ package body Packrat.Parsers is begin for R of Salt.Results loop if R.Finish >= Start then - Adjust.Insert (R); + Adjust.Include (R); end if; end loop; Salt.Results.Assign (Adjust); -- cgit