From 52403b22ff3463b9b3b0f8f26c0f965f50e4b458 Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Tue, 1 Dec 2020 23:14:41 +1100 Subject: Proper Allow_Incomplete behaviour in non-curtailing parser combinators --- src/packrat-parsers.adb | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb index bfb67d7..f49eca1 100644 --- a/src/packrat-parsers.adb +++ b/src/packrat-parsers.adb @@ -743,7 +743,14 @@ package body Packrat.Parsers is elsif Items'Length = 0 then return Empty (Input, Context, Start); end if; - My_Offset := Natural'Min (Input'Last - Start, Items'Length - 1); + 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; + end if; if Input (Start .. Start + My_Offset) /= Items (Items'First .. Items'First + My_Offset) then @@ -778,7 +785,14 @@ package body Packrat.Parsers is if Start > Input'Last then return Empty_Fail; end if; - My_Offset := Natural'Min (Input'Last - Start, Number - 1); + if Input'Last - Start < Number - 1 then + if not Context.Allow_Incomplete then + return Empty_Fail; + end if; + My_Offset := Input'Last - Start; + else + My_Offset := Number - 1; + end if; return Salt : Combinator_Result do Part.Finish := Start + My_Offset; Part.Value := Elem_Holds.To_Holder (Input (Start .. Start + My_Offset)); @@ -816,7 +830,8 @@ package body Packrat.Parsers is Part.Finish := My_Finish; Part.Value := Elem_Holds.To_Holder (Input (Start .. My_Finish)); Salt.Results.Insert (Part); - Salt.Status := (if My_Finish = Input'Last then Optional_More else Success); + Salt.Status := (if My_Finish = Input'Last and Context.Allow_Incomplete + then Optional_More else Success); end return; end Actual; function Call is new Memoize (To_Key (Start, Take_While'Access), Actual); @@ -849,7 +864,8 @@ package body Packrat.Parsers is Part.Finish := My_Finish; Part.Value := Elem_Holds.To_Holder (Input (Start .. My_Finish)); Salt.Results.Insert (Part); - Salt.Status := (if My_Finish = Input'Last then Optional_More else Success); + Salt.Status := (if My_Finish = Input'Last and Context.Allow_Incomplete + then Optional_More else Success); end return; end Actual; function Call is new Memoize (To_Key (Start, Take_Until'Access), Actual); -- cgit