summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2020-12-10 23:22:19 +1100
committerJed Barber <jjbarber@y7mail.com>2020-12-10 23:22:19 +1100
commit192172cfc44220975b34295d38c5213b08de5191 (patch)
tree555de972762414ba11e3e3f9908425dba55675f7
parentfb29719b1ce83fca511c1f310b388e0af65da257 (diff)
Some unit tests for Packrat.Parsers
-rw-r--r--test/packrat-parsers-debug.adb122
-rw-r--r--test/packrat-parsers-debug.ads76
-rw-r--r--test/rat_tests-parsers.adb736
-rw-r--r--test/rat_tests-parsers.ads85
-rw-r--r--test/test_main.adb21
5 files changed, 1034 insertions, 6 deletions
diff --git a/test/packrat-parsers-debug.adb b/test/packrat-parsers-debug.adb
new file mode 100644
index 0000000..744166a
--- /dev/null
+++ b/test/packrat-parsers-debug.adb
@@ -0,0 +1,122 @@
+
+
+with
+
+ Ada.Characters.Latin_1,
+ Ada.Strings.Unbounded;
+
+
+package body Packrat.Parsers.Debug is
+
+
+ package Latin renames Ada.Characters.Latin_1;
+ package SU renames Ada.Strings.Unbounded;
+
+
+
+
+
+ function Parts
+ (This : in Combinator_Result)
+ return Result_Part_Array
+ is
+ Arr : Result_Part_Array (1 .. Integer (This.Results.Length));
+ Index : Positive := 1;
+ begin
+ for R of This.Results loop
+ Arr (Index) := Result_Part (R);
+ Index := Index + 1;
+ end loop;
+ return Arr;
+ end Parts;
+
+
+ function Curtails
+ (This : in Combinator_Result)
+ return Curtail_Map is
+ begin
+ return (This.Curtails with null record);
+ end Curtails;
+
+
+ function Status
+ (This : in Combinator_Result)
+ return Result_Status is
+ begin
+ return This.Status;
+ end Status;
+
+
+
+
+
+ function Finish
+ (Part : in Result_Part)
+ return Traits.Tokens.Finish_Type is
+ begin
+ return Part.Finish;
+ end Finish;
+
+ function Value
+ (Part : in Result_Part)
+ return Traits.Element_Array is
+ begin
+ if Part.Value.Is_Empty then
+ return Arr : Traits.Element_Array (1 .. 0);
+ else
+ return Part.Value.Element;
+ end if;
+ end Value;
+
+ function Tokens
+ (Part : in Result_Part)
+ return Traits.Tokens.Finished_Token_Array is
+ begin
+ if Part.Tokens.Is_Empty then
+ return Arr : Traits.Tokens.Finished_Token_Array (1 .. 0);
+ else
+ return Part.Tokens.Element;
+ end if;
+ end Tokens;
+
+
+
+
+
+ function Is_Empty
+ (Curt : in Curtail_Map)
+ return Boolean is
+ begin
+ return Packrat.Parsers.Curtail_Maps.Map (Curt).Is_Empty;
+ end Is_Empty;
+
+
+
+
+
+ function Debug_String
+ (This : in Combinator_Result)
+ return String
+ is
+ Str : SU.Unbounded_String;
+ Index : Integer := 1;
+ begin
+ for Part of Parts (This) loop
+ SU.Append (Str, "Part" & Integer'Image (Index) & ":" & Latin.LF);
+ SU.Append (Str, Latin.HT & "Fin:" &
+ Traits.Tokens.Finish_Type'Image (Finish (Part)) & Latin.LF);
+ SU.Append (Str, Latin.HT & "Val:" & Integer'Image (Value (Part)'Length) & Latin.LF);
+ SU.Append (Str, Latin.HT & "Tok:" & Latin.LF);
+ for Tok of Tokens (Part) loop
+ SU.Append (Str, Latin.HT & Latin.HT & Traits.Tokens.Debug_String (Tok) & Latin.LF);
+ end loop;
+ Index := Index + 1;
+ end loop;
+ SU.Append (Str, Latin.HT & "Status: " & Result_Status'Image (Status (This)) & Latin.LF);
+ return -Str;
+ end Debug_String;
+
+
+end Packrat.Parsers.Debug;
+
+
diff --git a/test/packrat-parsers-debug.ads b/test/packrat-parsers-debug.ads
new file mode 100644
index 0000000..7fd425b
--- /dev/null
+++ b/test/packrat-parsers-debug.ads
@@ -0,0 +1,76 @@
+
+
+generic
+package Packrat.Parsers.Debug is
+
+
+ type Result_Part is private;
+ type Result_Part_Array is array (Positive range <>) of Result_Part;
+
+ type Curtail_Map is private;
+
+
+
+
+ Empty_Context : constant Parser_Context;
+ Empty_Fail : constant Combinator_Result;
+
+
+
+
+ function Parts
+ (This : in Combinator_Result)
+ return Result_Part_Array;
+
+ function Curtails
+ (This : in Combinator_Result)
+ return Curtail_Map;
+
+ function Status
+ (This : in Combinator_Result)
+ return Result_Status;
+
+
+
+
+ function Finish
+ (Part : in Result_Part)
+ return Traits.Tokens.Finish_Type;
+
+ function Value
+ (Part : in Result_Part)
+ return Traits.Element_Array;
+
+ function Tokens
+ (Part : in Result_Part)
+ return Traits.Tokens.Finished_Token_Array;
+
+
+
+
+ function Is_Empty
+ (Curt : in Curtail_Map)
+ return Boolean;
+
+
+
+
+ function Debug_String
+ (This : in Combinator_Result)
+ return String;
+
+
+private
+
+
+ type Result_Part is new Combo_Result_Part;
+ type Curtail_Map is new Curtail_Maps.Map with null record;
+
+
+ Empty_Context : constant Parser_Context := Packrat.Parsers.Empty_Context;
+ Empty_Fail : constant Combinator_Result := Packrat.Parsers.Empty_Fail;
+
+
+end Packrat.Parsers.Debug;
+
+
diff --git a/test/rat_tests-parsers.adb b/test/rat_tests-parsers.adb
new file mode 100644
index 0000000..9368d6d
--- /dev/null
+++ b/test/rat_tests-parsers.adb
@@ -0,0 +1,736 @@
+
+
+with
+
+ Ada.Text_IO,
+ Packrat.Utilities;
+
+
+package body Rat_Tests.Parsers is
+
+
+ use type Packrat.Result_Status;
+
+
+
+
+
+ function Alphanum_Switch
+ (Char : in Character)
+ return Character is
+ begin
+ case Char is
+ when 'a' .. 'z' =>
+ return Character'Val (48 + (Character'Pos (Char) - 97) mod 10);
+ when 'A' .. 'Z' =>
+ return Character'Val (48 + (Character'Pos (Char) - 65) mod 10);
+ when '0' .. '9' =>
+ return Character'Val (49 + (Character'Pos (Char)));
+ when others =>
+ return Char;
+ end case;
+ end Alphanum_Switch;
+
+
+
+
+
+ function Count_Check
+ return Test_Result
+ is
+ Input : String := "aaaa12aa";
+ Context1, Context2, Context3, Context4 : Pone.Parsers.Parser_Context :=
+ One_Debug.Empty_Context;
+ function Match_A is new Pone.Parsers.Match ('a');
+ function Three_A is new Pone.Parsers.Count (Match_A, 3);
+ Result1 : Pone.Parsers.Combinator_Result := Three_A (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Three_A (Input, Context2, 3);
+ Result3 : Pone.Parsers.Combinator_Result := Three_A (Input, Context3, 5);
+ Result4 : Pone.Parsers.Combinator_Result := Three_A (Input, Context4, 7);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Failure or
+ One_Debug.Status (Result4) /= Packrat.Needs_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ begin
+ if Result1_Parts'Length /= 1 or
+ One_Debug.Parts (Result2)'Length /= 0 or
+ One_Debug.Parts (Result3)'Length /= 0 or
+ One_Debug.Parts (Result4)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 3 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Count_Check;
+
+
+ function Many_Nomin_Check
+ return Test_Result
+ is
+ Input : String := "abcd123efghi";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Sat_Letter is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Letter);
+ function Many_Letter is new Pone.Parsers.Many (Sat_Letter, 0);
+ Result1 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context2, 5);
+ Result3 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context3, 8);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Optional_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 5 or
+ Result2_Parts'Length /= 1 or
+ Result3_Parts'Length /= 6
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 0 or
+ One_Debug.Finish (Result1_Parts (2)) /= 1 or
+ One_Debug.Finish (Result1_Parts (3)) /= 2 or
+ One_Debug.Finish (Result1_Parts (4)) /= 3 or
+ One_Debug.Finish (Result1_Parts (5)) /= 4
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Value (Result1_Parts (2))'Length /= 1 or
+ One_Debug.Value (Result1_Parts (3))'Length /= 2 or
+ One_Debug.Value (Result1_Parts (4))'Length /= 3 or
+ One_Debug.Value (Result1_Parts (5))'Length /= 4
+ then
+ return Fail;
+ end if;
+ if (for some P of Result1_Parts => One_Debug.Tokens (P)'Length /= 0) then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result2_Parts (1)) /= 4 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result3_Parts (1)) /= 7 or
+ One_Debug.Finish (Result3_Parts (2)) /= 8 or
+ One_Debug.Finish (Result3_Parts (3)) /= 9 or
+ One_Debug.Finish (Result3_Parts (4)) /= 10 or
+ One_Debug.Finish (Result3_Parts (5)) /= 11 or
+ One_Debug.Finish (Result3_Parts (6)) /= 12
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result3_Parts (1))'Length /= 0 or
+ One_Debug.Value (Result3_Parts (2))'Length /= 1 or
+ One_Debug.Value (Result3_Parts (3))'Length /= 2 or
+ One_Debug.Value (Result3_Parts (4))'Length /= 3 or
+ One_Debug.Value (Result3_Parts (5))'Length /= 4 or
+ One_Debug.Value (Result3_Parts (6))'Length /= 5
+ then
+ return Fail;
+ end if;
+ if (for some P of Result3_Parts => One_Debug.Tokens (P)'Length /= 0) then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Many_Nomin_Check;
+
+
+ function Many_Min_Check
+ return Test_Result
+ is
+ Input : String := "abcd123efghi";
+ Context1, Context2, Context3, Context4 : Pone.Parsers.Parser_Context :=
+ One_Debug.Empty_Context;
+ function Sat_Letter is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Letter);
+ function Many_Letter is new Pone.Parsers.Many (Sat_Letter, 3);
+ Result1 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context2, 5);
+ Result3 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context3, 8);
+ Result4 : Pone.Parsers.Combinator_Result := Many_Letter (Input, Context4, 11);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Optional_More or
+ One_Debug.Status (Result4) /= Packrat.Needs_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 2 or
+ One_Debug.Parts (Result2)'Length /= 0 or
+ Result3_Parts'Length /= 3 or
+ One_Debug.Parts (Result4)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Finish (Result1_Parts (2)) /= 4
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result1_Parts (1))'Length /= 3 or
+ One_Debug.Value (Result1_Parts (2))'Length /= 4
+ then
+ return Fail;
+ end if;
+ if One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result1_Parts (2))'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result3_Parts (1)) /= 10 or
+ One_Debug.Finish (Result3_Parts (2)) /= 11 or
+ One_Debug.Finish (Result3_Parts (3)) /= 12
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result3_Parts (1))'Length /= 3 or
+ One_Debug.Value (Result3_Parts (2))'Length /= 4 or
+ One_Debug.Value (Result3_Parts (3))'Length /= 5
+ then
+ return Fail;
+ end if;
+ if One_Debug.Tokens (Result3_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result3_Parts (2))'Length /= 0 or
+ One_Debug.Tokens (Result3_Parts (3))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Many_Min_Check;
+
+
+ function Many_Until_Nomin_Check
+ return Test_Result
+ is
+ Input : String := "abc12de;fghi";
+ Context1, Context2, Context3, Context4 : Pone.Parsers.Parser_Context :=
+ One_Debug.Empty_Context;
+ function Sat_Letter is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Letter);
+ function Sat_Digit is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Digit);
+ function Body_Is_Dry is new Pone.Parsers.Many_Until (Sat_Letter, Sat_Digit, 0);
+ Result1 : Pone.Parsers.Combinator_Result := Body_Is_Dry (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Body_Is_Dry (Input, Context2, 4);
+ Result3 : Pone.Parsers.Combinator_Result := Body_Is_Dry (Input, Context3, 6);
+ Result4 : Pone.Parsers.Combinator_Result := Body_Is_Dry (Input, Context4, 9);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Failure or
+ One_Debug.Status (Result4) /= Packrat.Needs_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ begin
+ if Result1_Parts'Length /= 1 or
+ Result2_Parts'Length /= 1 or
+ One_Debug.Parts (Result3)'Length /= 0 or
+ One_Debug.Parts (Result4)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 3 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result2_Parts (1)) /= 3 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Many_Until_Nomin_Check;
+
+
+ function Many_Until_Min_Check
+ return Test_Result
+ is
+ Input : String := "abcde12fgh";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Sat_Letter is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Letter);
+ function Sat_Digit is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Digit);
+ function Your_Way is new Pone.Parsers.Many_Until (Sat_Letter, Sat_Digit, 3);
+ Result1 : Pone.Parsers.Combinator_Result := Your_Way (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Your_Way (Input, Context2, 4);
+ Result3 : Pone.Parsers.Combinator_Result := Your_Way (Input, Context3, 8);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Needs_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ begin
+ if Result1_Parts'Length /= 1 or
+ One_Debug.Parts (Result2)'Length /= 0 or
+ One_Debug.Parts (Result3)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 5 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 5 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Many_Until_Min_Check;
+
+
+ function Satisfy_Check
+ return Test_Result
+ is
+ Input : String := "abc123def";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Satisfy_Letter is new Pone.Parsers.Satisfy (Packrat.Utilities.Is_Letter);
+ Result1 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context1, 2);
+ Result2 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context2, 6);
+ Result3 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context3, 10);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 1 or
+ Result2_Parts'Length /= 0 or
+ Result3_Parts'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 2 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 1 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Satisfy_Check;
+
+
+ function Satisfy_With_Check
+ return Test_Result
+ is
+ Input : String := "abc123def";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Satisfy_Letter is new Pone.Parsers.Satisfy_With
+ (Packrat.Utilities.Is_Letter, Alphanum_Switch);
+ Result1 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context1, 2);
+ Result2 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context2, 6);
+ Result3 : Pone.Parsers.Combinator_Result := Satisfy_Letter (Input, Context3, 10);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Failure or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 0 or
+ Result2_Parts'Length /= 1 or
+ Result3_Parts'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result2_Parts (1)) /= 6 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 1 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Satisfy_With_Check;
+
+
+ function Match_Check
+ return Test_Result
+ is
+ Input : String := "aaabbbccc";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Match_B is new Pone.Parsers.Match ('b');
+ Result1 : Pone.Parsers.Combinator_Result := Match_B (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Match_B (Input, Context2, 5);
+ Result3 : Pone.Parsers.Combinator_Result := Match_B (Input, Context3, 200);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Failure or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 0 or
+ Result2_Parts'Length /= 1 or
+ Result3_Parts'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result2_Parts (1)) /= 5 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 1 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Match_Check;
+
+
+ function Match_With_Check
+ return Test_Result
+ is
+ Input : String := "aaa111b2";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Match_0 is new Pone.Parsers.Match_With ('0', Alphanum_Switch);
+ Result1 : Pone.Parsers.Combinator_Result := Match_0 (Input, Context1, 3);
+ Result2 : Pone.Parsers.Combinator_Result := Match_0 (Input, Context2, 4);
+ Result3 : Pone.Parsers.Combinator_Result := Match_0 (Input, Context3, 7);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 1 or
+ Result2_Parts'Length /= 0 or
+ Result3_Parts'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 1 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Match_With_Check;
+
+
+ function Multimatch_Check
+ return Test_Result
+ is
+ Input : String := "abcdefghi";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Multi is new Pone.Parsers.Multimatch ("def");
+ Result1 : Pone.Parsers.Combinator_Result := Multi (Input, Context1, 2);
+ Result2 : Pone.Parsers.Combinator_Result := Multi (Input, Context2, 4);
+ Result3 : Pone.Parsers.Combinator_Result := Multi (Input, Context3, 300);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Failure or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ begin
+ if One_Debug.Parts (Result1)'Length /= 0 or
+ Result2_Parts'Length /= 1 or
+ One_Debug.Parts (Result3)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result2_Parts (1)) /= 6 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 3 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Multimatch_Check;
+
+
+ function Take_Check
+ return Test_Result
+ is
+ Input : String := "abcdefghi";
+ Context1, Context2, Context3, Context4 : Pone.Parsers.Parser_Context :=
+ One_Debug.Empty_Context;
+ function Take_2 is new Pone.Parsers.Take (2);
+ function Take_5 is new Pone.Parsers.Take (5);
+ Result1 : Pone.Parsers.Combinator_Result := Take_2 (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Take_5 (Input, Context2, 3);
+ Result3 : Pone.Parsers.Combinator_Result := Take_5 (Input, Context3, 7);
+ Result4 : Pone.Parsers.Combinator_Result := Take_2 (Input, Context4, 100);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Needs_More or
+ One_Debug.Status (Result4) /= Packrat.Failure
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ begin
+ if Result1_Parts'Length /= 1 or
+ Result2_Parts'Length /= 1 or
+ One_Debug.Parts (Result3)'Length /= 0 or
+ One_Debug.Parts (Result4)'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 2 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 2 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Finish (Result2_Parts (1)) /= 7 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 5 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Take_Check;
+
+
+ function Take_While_Check
+ return Test_Result
+ is
+ Input : String := "abc123def";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Take_On_Me is new Pone.Parsers.Take_While (Packrat.Utilities.Is_Letter);
+ Result1 : Pone.Parsers.Combinator_Result := Take_On_Me (Input, Context1, 2);
+ Result2 : Pone.Parsers.Combinator_Result := Take_On_Me (Input, Context2, 4);
+ Result3 : Pone.Parsers.Combinator_Result := Take_On_Me (Input, Context3, 7);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Optional_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 1 or
+ One_Debug.Parts (Result2)'Length /= 0 or
+ Result3_Parts'Length /= 1
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 2 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Finish (Result3_Parts (1)) /= 9 or
+ One_Debug.Value (Result3_Parts (1))'Length /= 3 or
+ One_Debug.Tokens (Result3_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Take_While_Check;
+
+
+ function Take_Until_Check
+ return Test_Result
+ is
+ Input : String := "abc123def";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Take_Me_On is new Pone.Parsers.Take_Until (Packrat.Utilities.Is_Digit);
+ Result1 : Pone.Parsers.Combinator_Result := Take_Me_On (Input, Context1, 2);
+ Result2 : Pone.Parsers.Combinator_Result := Take_Me_On (Input, Context2, 6);
+ Result3 : Pone.Parsers.Combinator_Result := Take_Me_On (Input, Context3, 8);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Failure or
+ One_Debug.Status (Result3) /= Packrat.Optional_More
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 1 or
+ One_Debug.Parts (Result2)'Length /= 0 or
+ Result3_Parts'Length /= 1
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 3 or
+ One_Debug.Value (Result1_Parts (1))'Length /= 2 or
+ One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Finish (Result3_Parts (1)) /= 9 or
+ One_Debug.Value (Result3_Parts (1))'Length /= 2 or
+ One_Debug.Tokens (Result3_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Take_Until_Check;
+
+
+ function Empty_Check
+ return Test_Result
+ is
+ Input : String := "abcdef";
+ Context1, Context2, Context3 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ Result1 : Pone.Parsers.Combinator_Result := Pone.Parsers.Empty (Input, Context1, 1);
+ Result2 : Pone.Parsers.Combinator_Result := Pone.Parsers.Empty (Input, Context2, 3);
+ Result3 : Pone.Parsers.Combinator_Result := Pone.Parsers.Empty (Input, Context3, 10);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Success or
+ One_Debug.Status (Result2) /= Packrat.Success or
+ One_Debug.Status (Result3) /= Packrat.Success
+ then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ Result2_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result2);
+ Result3_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result3);
+ begin
+ if Result1_Parts'Length /= 1 or
+ Result2_Parts'Length /= 1 or
+ Result3_Parts'Length /= 1
+ then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 0 or
+ One_Debug.Finish (Result2_Parts (1)) /= 2 or
+ One_Debug.Finish (Result3_Parts (1)) /= 9
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Value (Result2_Parts (1))'Length /= 0 or
+ One_Debug.Value (Result3_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ if One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result2_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result3_Parts (1))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Empty_Check;
+
+
+ function Not_Empty_Check
+ return Test_Result
+ is
+ Input : String := "aa";
+ Context1 : Pone.Parsers.Parser_Context := One_Debug.Empty_Context;
+ function Match_A is new Pone.Parsers.Match ('a');
+ function Many_A is new Pone.Parsers.Many (Match_A, 0);
+ function NE_Many_A is new Pone.Parsers.Not_Empty (Many_A);
+ Result1 : Pone.Parsers.Combinator_Result := NE_Many_A (Input, Context1, 1);
+ begin
+ if One_Debug.Status (Result1) /= Packrat.Optional_More then
+ return Fail;
+ end if;
+ declare
+ Result1_Parts : One_Debug.Result_Part_Array := One_Debug.Parts (Result1);
+ begin
+ if Result1_Parts'Length /= 2 then
+ return Fail;
+ end if;
+ if One_Debug.Finish (Result1_Parts (1)) /= 1 or
+ One_Debug.Finish (Result1_Parts (2)) /= 2
+ then
+ return Fail;
+ end if;
+ if One_Debug.Value (Result1_Parts (1))'Length /= 1 or
+ One_Debug.Value (Result1_Parts (2))'Length /= 2
+ then
+ return Fail;
+ end if;
+ if One_Debug.Tokens (Result1_Parts (1))'Length /= 0 or
+ One_Debug.Tokens (Result1_Parts (2))'Length /= 0
+ then
+ return Fail;
+ end if;
+ end;
+ return Pass;
+ end Not_Empty_Check;
+
+
+
+
+
+ function Default_Result_Check
+ return Test_Result
+ is
+ Default : Pone.Parsers.Combinator_Result;
+ begin
+ if One_Debug.Status (Default) /= Packrat.Failure or
+ One_Debug.Parts (Default)'Length /= 0 or
+ not One_Debug.Is_Empty (One_Debug.Curtails (Default))
+ then
+ return Fail;
+ end if;
+ return Pass;
+ end Default_Result_Check;
+
+
+end Rat_Tests.Parsers;
+
+
diff --git a/test/rat_tests-parsers.ads b/test/rat_tests-parsers.ads
new file mode 100644
index 0000000..a70f41e
--- /dev/null
+++ b/test/rat_tests-parsers.ads
@@ -0,0 +1,85 @@
+
+
+with
+
+ Unit_Tests;
+
+use
+
+ Unit_Tests;
+
+private with
+
+ Packrat.No_Lex,
+ Packrat.Parsers.Debug,
+ Packrat.Errors,
+ Packrat.Traits;
+
+
+package Rat_Tests.Parsers is
+
+
+ function Count_Check return Test_Result;
+ function Many_Nomin_Check return Test_Result;
+ function Many_Min_Check return Test_Result;
+
+ function Many_Until_Nomin_Check return Test_Result;
+ function Many_Until_Min_Check return Test_Result;
+
+ function Satisfy_Check return Test_Result;
+ function Satisfy_With_Check return Test_Result;
+ function Match_Check return Test_Result;
+ function Match_With_Check return Test_Result;
+ function Multimatch_Check return Test_Result;
+ function Take_Check return Test_Result;
+ function Take_While_Check return Test_Result;
+ function Take_Until_Check return Test_Result;
+
+ function Empty_Check return Test_Result;
+ function Not_Empty_Check return Test_Result;
+
+ Combinator_Tests : Test_Array :=
+ ((+"Count", Count_Check'Access),
+ (+"Many No Minimum", Many_Nomin_Check'Access),
+ (+"Many With Minimum", Many_Min_Check'Access),
+ (+"Many_Until No Minimum", Many_Until_Nomin_Check'Access),
+ (+"Many_Until With Minimum", Many_Until_Min_Check'Access),
+ (+"Satisfy", Satisfy_Check'Access),
+ (+"Satisfy_With", Satisfy_With_Check'Access),
+ (+"Match", Match_Check'Access),
+ (+"Match_With", Match_With_Check'Access),
+ (+"Multimatch", Multimatch_Check'Access),
+ (+"Take", Take_Check'Access),
+ (+"Take_While", Take_While_Check'Access),
+ (+"Take_Until", Take_Until_Check'Access),
+ (+"Empty", Empty_Check'Access),
+ (+"Not_Empty", Not_Empty_Check'Access));
+
+
+ function Default_Result_Check return Test_Result;
+
+ Other_Tests : Test_Array :=
+ (1 => (+"Default Combinator Result", Default_Result_Check'Access));
+
+
+private
+
+
+ type Parser_Labels_One is (One, Two, Three, Four, Five, Six);
+
+ package Pone is new Packrat.No_Lex
+ (Parser_Labels_One, Character, String);
+
+ package One_Debug is new Pone.Parsers.Debug;
+
+
+
+
+ function Alphanum_Switch
+ (Char : in Character)
+ return Character;
+
+
+end Rat_Tests.Parsers;
+
+
diff --git a/test/test_main.adb b/test/test_main.adb
index 1edf4e6..3fdab35 100644
--- a/test/test_main.adb
+++ b/test/test_main.adb
@@ -12,7 +12,8 @@ with
Rat_Tests.Tokens,
Rat_Tests.Lexers,
Rat_Tests.Utilities,
- Rat_Tests.Parse_Graphs;
+ Rat_Tests.Parse_Graphs,
+ Rat_Tests.Parsers;
use
@@ -45,6 +46,7 @@ procedure Test_Main is
Err : Packrat.Errors.Error_Message := Packrat.Errors.Encode ("A", 1);
Tok : My_Tokens.Token_Type := My_Tokens.Create (A, 1, "abc");
+ Fin_Tok : My_Tokens.Finished_Token_Type := (Tok, 5);
begin
@@ -75,15 +77,15 @@ begin
Put_Line ("Running tests for Packrat.Tokens...");
Run_Tests (Rat_Tests.Tokens.Tests, How_Verbose);
New_Line;
- Put_Line ("Displaying Token debug string output example:");
+ Put_Line ("Displaying Token debug string output examples:");
Put (My_Tokens.Debug_String (Tok));
+ Put (My_Tokens.Debug_String (Fin_Tok));
New_Line;
- Put_Line ("Running tests for Packrat.Lexers combinators...");
+ Put_Line ("Running tests for Packrat.Lexers...");
+ Put_Line ("Testing lexer combinators...");
Run_Tests (Rat_Tests.Lexers.Combinator_Tests, How_Verbose);
- New_Line;
-
- Put_Line ("Running tests for Packrat.Lexers lexing...");
+ Put_Line ("Testing lexer scanners...");
Run_Tests (Rat_Tests.Lexers.Lexer_Tests, How_Verbose);
New_Line;
@@ -99,6 +101,13 @@ begin
New_Line;
Put_Line ("Displaying Parse_Graph debug string output example:");
Put (Rat_Tests.Parse_Graphs.Debug_String_Check);
+ New_Line;
+
+ Put_Line ("Running tests for Packrat.Parsers...");
+ Put_Line ("Testing parser combinators...");
+ Run_Tests (Rat_Tests.Parsers.Combinator_Tests, How_Verbose);
+ Put_Line ("Testing other tests...");
+ Run_Tests (Rat_Tests.Parsers.Other_Tests, How_Verbose);
end Test_Main;