From 0b0c4df3dc7b94c139c5305ea0991a34f0c43238 Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Thu, 21 Jan 2021 20:01:23 +1100 Subject: Lexer combinator Needs_More case fixed --- src/packrat-lexers.adb | 35 +++++++++++++++++----------------- src/packrat-lexers.ads | 8 ++++++++ test/rat_tests-lexers.adb | 48 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/packrat-lexers.adb b/src/packrat-lexers.adb index b09b6eb..341b87f 100644 --- a/src/packrat-lexers.adb +++ b/src/packrat-lexers.adb @@ -417,7 +417,7 @@ package body Packrat.Lexers is Position : Positive := Start; begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; end if; for C of Params loop if Position > Input'Last then @@ -441,7 +441,7 @@ package body Packrat.Lexers is Position : Positive := Start; begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; end if; for I in Integer range 1 .. Number loop if Position > Input'Last then @@ -467,7 +467,7 @@ package body Packrat.Lexers is Counter : Natural := 0; begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; end if; loop exit when Position > Input'Last; @@ -503,7 +503,7 @@ package body Packrat.Lexers is Counter : Natural := 0; begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; end if; loop exit when Position > Input'Last; @@ -541,7 +541,7 @@ package body Packrat.Lexers is return Combinator_Result is begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; elsif Test (Input (Start)) then return (Start, Success); else @@ -556,7 +556,7 @@ package body Packrat.Lexers is return Combinator_Result is begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; elsif Test (Change (Input (Start))) then return (Start, Success); else @@ -571,7 +571,7 @@ package body Packrat.Lexers is return Combinator_Result is begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; elsif Input (Start) = Item then return (Start, Success); else @@ -586,7 +586,7 @@ package body Packrat.Lexers is return Combinator_Result is begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; elsif Change (Input (Start)) = Item then return (Start, Success); else @@ -603,13 +603,10 @@ package body Packrat.Lexers is Current_Offset : Natural := 0; begin if Items'Length = 0 then - return (0, Success); + return Empty_Success; + elsif Start > Input'Last then + return Empty_Needs_More; end if; - - if Input'Last - Start + 1 <= 0 then - return Empty_Fail; - end if; - while Input (Start + Current_Offset) = Items (Items'First + Current_Offset) loop if Items'First + Current_Offset = Items'Last then return (Start + Current_Offset, Success); @@ -632,7 +629,7 @@ package body Packrat.Lexers is return Combinator_Result is begin if Start > Input'Last then - return Empty_Fail; + return Empty_Needs_More; elsif Start + Number - 1 > Input'Last then return (Input'Last, Needs_More); else @@ -649,7 +646,9 @@ package body Packrat.Lexers is Finish : Positive := Start; Status : Result_Status; begin - if Start > Input'Last or else not Test (Input (Start)) then + if Start > Input'Last then + return Empty_Needs_More; + elsif not Test (Input (Start)) then return Empty_Fail; end if; while Finish <= Input'Last and then Test (Input (Finish)) loop @@ -672,7 +671,9 @@ package body Packrat.Lexers is Finish : Positive := Start; Status : Result_Status; begin - if Start > Input'Last or else Test (Input (Start)) then + if Start > Input'Last then + return Empty_Needs_More; + elsif Test (Input (Start)) then return Empty_Fail; end if; while Finish <= Input'Last and then not Test (Input (Finish)) loop diff --git a/src/packrat-lexers.ads b/src/packrat-lexers.ads index 4b6bbc9..c303feb 100644 --- a/src/packrat-lexers.ads +++ b/src/packrat-lexers.ads @@ -305,6 +305,14 @@ private (Finish => 0, Status => Failure); + Empty_Needs_More : constant Combinator_Result := + (Finish => 0, + Status => Needs_More); + + Empty_Success : constant Combinator_Result := + (Finish => 0, + Status => Success); + diff --git a/test/rat_tests-lexers.adb b/test/rat_tests-lexers.adb index 6d8c34f..f508b2b 100644 --- a/test/rat_tests-lexers.adb +++ b/test/rat_tests-lexers.adb @@ -88,11 +88,13 @@ package body Rat_Tests.Lexers is Result4 : Slexy.Combinator_Result := Slebug.Empty_Fail; Result5 : Slexy.Combinator_Result := Slebug.Create_Result (3, Packrat.Failure); + Result6 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Seq_Abc (Test_Str, 1) /= Result1 or Seq_Abc (Test_Str, 2) /= Result5 or Seq_Abc (Test_Str, 4) /= Result3 or Seq_Abc (Test_Str, 10) /= Result2 or Seq_Abc (Test_Str, 3) /= Result4 or - Seq_Abc (Test_Str, Test_Str'Last + 5) /= Result4 + Seq_Abc (Test_Str, Test_Str'Last + 5) /= Result6 then return Fail; end if; @@ -121,12 +123,14 @@ package body Rat_Tests.Lexers is Result5 : Slexy.Combinator_Result := Slebug.Create_Result (12, Packrat.Success); Result6 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result7 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Count_2A (Test_Str, 1) /= Result1 or Count_2A (Test_Str, 3) /= Result2 or Count_3B (Test_Str, 2) /= Result3 or Count_3B (Test_Str, 19) /= Result4 or Count_3B (Test_Str, 10) /= Result5 or Count_3B (Test_Str, 1) /= Result6 or Count_2A (Test_Str, 2) /= Result6 or - Count_2A (Test_Str, Test_Str'Last + 5) /= Result6 + Count_2A (Test_Str, Test_Str'Last + 5) /= Result7 then return Fail; end if; @@ -161,7 +165,8 @@ package body Rat_Tests.Lexers is Slebug.Create_Result (10, Packrat.Success); Result4 : Slexy.Combinator_Result := Slebug.Create_Result (3, Packrat.Failure); - Result5 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result5 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); Result6 : Slexy.Combinator_Result := Slebug.Create_Result (13, Packrat.Needs_More); Result7 : Slexy.Combinator_Result := @@ -199,14 +204,16 @@ package body Rat_Tests.Lexers is Result3 : Slexy.Combinator_Result := Slebug.Create_Result (15, Packrat.Needs_More); Result4 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result5 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Many_Until_0 (Test_Str, 1) /= Result1 or Many_Until_0 (Test_Str, 7) /= Result2 or Many_Until_3 (Test_Str, 7) /= Result2 or Many_Until_3 (Test_Str, 13) /= Result3 or Many_Until_0 (Test_Str, 5) /= Result4 or - Many_Until_0 (Test_Str, Test_Str'Last + 5) /= Result4 or - Many_Until_3 (Test_Str, Test_Str'Last + 5) /= Result4 + Many_Until_0 (Test_Str, Test_Str'Last + 5) /= Result5 or + Many_Until_3 (Test_Str, Test_Str'Last + 5) /= Result5 then return Fail; end if; @@ -240,11 +247,13 @@ package body Rat_Tests.Lexers is Result2 : Slexy.Combinator_Result := Slebug.Create_Result (6, Packrat.Success); Result3 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result4 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Satisfy_123 (Test_Str, 6) /= Result2 or Satisfy_Abc (Test_Str, 2) /= Result1 or Satisfy_Abc (Test_Str, 8) /= Result3 or - Satisfy_123 (Test_Str, Test_Str'Last + 5) /= Result3 + Satisfy_123 (Test_Str, Test_Str'Last + 5) /= Result4 then return Fail; end if; @@ -284,11 +293,13 @@ package body Rat_Tests.Lexers is Result2 : Slexy.Combinator_Result := Slebug.Create_Result (7, Packrat.Success); Result3 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result4 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Satisfy_Bcd (Test_Str, 3) /= Result1 or Satisfy_234 (Test_Str, 7) /= Result2 or Satisfy_Bcd (Test_Str, 1) /= Result3 or - Satisfy_234 (Test_Str, Test_Str'Last + 5) /= Result3 + Satisfy_234 (Test_Str, Test_Str'Last + 5) /= Result4 then return Fail; end if; @@ -312,12 +323,14 @@ package body Rat_Tests.Lexers is Result3 : Slexy.Combinator_Result := Slebug.Create_Result (7, Packrat.Success); Result4 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result5 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Match_A (Test_Str, 1) /= Result1 or Match_Slash (Test_Str, 9) /= Result2 or Match_4 (Test_Str, 7) /= Result3 or Match_A (Test_Str, 3) /= Result4 or - Match_A (Test_Str, Test_Str'Last + 5) /= Result4 + Match_A (Test_Str, Test_Str'Last + 5) /= Result5 then return Fail; end if; @@ -345,11 +358,13 @@ package body Rat_Tests.Lexers is Result2 : Slexy.Combinator_Result := Slebug.Create_Result (5, Packrat.Success); Result3 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result4 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Match_A (Test_Str, 1) /= Result1 or Match_6 (Test_Str, 5) /= Result2 or Match_A (Test_Str, 2) /= Result3 or - Match_A (Test_Str, Test_Str'Last + 5) /= Result3 + Match_A (Test_Str, Test_Str'Last + 5) /= Result4 then return Fail; end if; @@ -374,13 +389,15 @@ package body Rat_Tests.Lexers is Result4 : Slexy.Combinator_Result := Slebug.Create_Result (8, Packrat.Failure); Result5 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result6 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Match_String1 (Test_Str, 1) /= Result1 or Match_String1 (Test_Str, 7) /= Result4 or Match_String2 (Test_Str, 9) /= Result3 or Match_String2 (Test_Str, 3) /= Result5 or Match_String1 (Test_Str, 19) /= Result2 or - Match_String1 (Test_Str, Test_Str'Last + 5) /= Result5 + Match_String1 (Test_Str, Test_Str'Last + 5) /= Result6 then return Fail; end if; @@ -402,7 +419,8 @@ package body Rat_Tests.Lexers is Slebug.Create_Result (9, Packrat.Needs_More); Result3 : Slexy.Combinator_Result := Slebug.Create_Result (7, Packrat.Success); - Result4 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result4 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Take_1 (Test_Str, 2) /= Result1 or Take_5 (Test_Str, 7) /= Result2 or Take_5 (Test_Str, 3) /= Result3 or @@ -434,13 +452,15 @@ package body Rat_Tests.Lexers is Result5 : Slexy.Combinator_Result := Slebug.Empty_Fail; Result6 : Slexy.Combinator_Result := Slebug.Create_Result (22, Packrat.Optional_More); + Result7 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Take_Letters (Test_Str, 2) /= Result1 or Take_Letters (Test_Str, 13) /= Result2 or Take_Punch (Test_Str, 6) /= Result3 or Take_Punch (Test_Str, 17) /= Result4 or Take_Letters (Test_Str, 7) /= Result5 or - Take_Punch (Test_Str, Test_Str'Last + 5) /= Result5 or + Take_Punch (Test_Str, Test_Str'Last + 5) /= Result7 or Take_Digits (Test_Str, 20) /= Result6 then return Fail; @@ -466,13 +486,15 @@ package body Rat_Tests.Lexers is Result4 : Slexy.Combinator_Result := Slebug.Create_Result (17, Packrat.Success); Result5 : Slexy.Combinator_Result := Slebug.Empty_Fail; + Result6 : Slexy.Combinator_Result := + Slebug.Create_Result (0, Packrat.Needs_More); begin if Take_Till_Punch (Test_Str, 4) /= Result1 or Take_Till_Punch (Test_Str, 16) /= Result2 or Take_Till_Digit (Test_Str, 1) /= Result3 or Take_Till_Digit (Test_Str, 12) /= Result4 or Take_Till_Punch (Test_Str, 11) /= Result5 or - Take_Till_Punch (Test_Str, Test_Str'Last + 5) /= Result5 + Take_Till_Punch (Test_Str, Test_Str'Last + 5) /= Result6 then return Fail; end if; -- cgit