From 2adeae8eb1bc8437b392bed07f1858363f95ab8a Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Sat, 12 Dec 2020 12:49:01 +1100 Subject: More bugfixes and Parser unit tests --- src/packrat-parsers.adb | 119 ++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 64 deletions(-) (limited to 'src/packrat-parsers.adb') diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb index 875a765..63dcb00 100644 --- a/src/packrat-parsers.adb +++ b/src/packrat-parsers.adb @@ -9,13 +9,40 @@ with 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 Traits.Tokens.Finished_Token_Array is + begin + if Hold.Is_Empty then + return Value : Traits.Tokens.Finished_Token_Array (1 .. 0); + else + return Hold.Element; + end if; + end Element; + + + + + function "<" (Left, Right : in Elem_Holds.Holder) return Boolean is use Traits; begin - return Left.Element < Right.Element; + return Element (Left) < Element (Right); end "<"; @@ -25,7 +52,7 @@ package body Packrat.Parsers is is use type Traits.Tokens.Finished_Token_Array; begin - return Left.Element < Right.Element; + return Element (Left) < Element (Right); end "<"; @@ -72,33 +99,6 @@ 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 Traits.Tokens.Finished_Token_Array is - begin - if Hold.Is_Empty then - return Value : Traits.Tokens.Finished_Token_Array (1 .. 0); - else - return Hold.Element; - end if; - end Element; - - - - - function To_Key (Start : in Positive; Func : access function @@ -268,7 +268,9 @@ package body Packrat.Parsers is when Optional_More => Target.Results.Union (Add.Results); Target.Status := Optional_More; - when Needs_More | Failure => + when Needs_More => + Target.Status := Optional_More; + when Failure => null; end case; when Optional_More => @@ -283,9 +285,7 @@ package body Packrat.Parsers is when Success | Optional_More => Target := Add; Target.Status := Optional_More; - when Needs_More => - Target.Results.Union (Add.Results); - when Failure => + when Needs_More | Failure => null; end case; when Failure => @@ -663,9 +663,7 @@ package body Packrat.Parsers is is Salt : Combinator_Result; begin - if Start > Input'Last then - return Empty_Fail; - elsif Params'Length = 0 then + if Params'Length = 0 then return Empty (Input, Context, Start); end if; Salt := Params (Params'First) (Input, Context, Start); @@ -725,9 +723,7 @@ package body Packrat.Parsers is is Salt : Combinator_Result; begin - if Start > Input'Last then - return Empty_Fail; - elsif Params'Length = 0 then + if Params'Length = 0 then return Empty (Input, Context, Start); end if; for C of Params loop @@ -779,9 +775,6 @@ package body Packrat.Parsers is Salt : Combinator_Result; Counter : Natural := 0; begin - if Start > Input'Last then - return Empty_Fail; - end if; Salt := Param (Input, Context, Start); while Salt.Status /= Failure loop Counter := Counter + 1; @@ -820,9 +813,6 @@ package body Packrat.Parsers is Salt, Temp : Combinator_Result; Counter : Natural := 0; begin - if Start > Input'Last then - return Salt; - end if; if Minimum = 0 then Merge (Salt, Empty (Input, Context, Start)); end if; @@ -911,7 +901,13 @@ package body Packrat.Parsers is return Empty (Input, Context, Start); end if; when Failure => - return Empty (Input, Context, Start); + if Context.Allow_Incomplete and Start > Input'Last then + return Salt : Combinator_Result do + Salt.Status := Needs_More; + end return; + else + return Empty (Input, Context, Start); + end if; end case; end Actual; function Curt is new Curtailment (To_Key (Start, Not_Followed_By'Access), Input, Actual); @@ -960,9 +956,6 @@ package body Packrat.Parsers is function Not_Empty_Param is new Not_Empty (Param); Salt : Combinator_Result := Empty (Input, Context, Start); begin - if Start > Input'Last then - return Empty_Fail; - end if; Merge (Salt, Not_Empty_Param (Input, Context, Start)); Complete_Status (Salt, Context.Allow_Incomplete); return Salt; @@ -1174,31 +1167,29 @@ package body Packrat.Parsers is is use type Traits.Element_Array; Part : Combo_Result_Part; - My_Offset : Natural; begin if Start > Input'Last then - return Empty_Fail; + return Salt : Combinator_Result; elsif Items'Length = 0 then return Empty (Input, Context, Start); end if; if Input'Last - Start < Items'Length - 1 then - if not Context.Allow_Incomplete then - return Empty_Fail; - end if; - My_Offset := Input'Last - Start; - else - My_Offset := Items'Length - 1; + return Salt : Combinator_Result do + if Context.Allow_Incomplete and Input (Start .. Input'Last) = + Items (Items'First .. Items'First + Input'Last - Start) + then + Salt.Status := Needs_More; + end if; + end return; end if; - if Input (Start .. Start + My_Offset) /= - Items (Items'First .. Items'First + My_Offset) - then - return Empty_Fail; + if Input (Start .. Start + Items'Length - 1) /= Items (Items'First .. Items'Last) then + return Salt : Combinator_Result; end if; return Salt : Combinator_Result do - Part.Finish := Start + My_Offset; - Part.Value := Elem_Holds.To_Holder (Input (Start .. Start + My_Offset)); + Part.Finish := Start + Items'Length - 1; + Part.Value := Elem_Holds.To_Holder (Input (Start .. Start + Items'Length - 1)); Salt.Results.Include (Part); - Salt.Status := (if My_Offset < Items'Length - 1 then Needs_More else Success); + Salt.Status := Success; end return; end Actual; function Call is new Memoize (To_Key (Start, Multimatch'Access), Actual); -- cgit