summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2019-01-13 20:19:48 +1100
committerJed Barber <jjbarber@y7mail.com>2019-01-13 20:19:48 +1100
commitf8cef7edffc705cc1c168620a6ba0e76a90f6366 (patch)
tree3b783cb06805b07874cc271b4a2f935355742e41
parente56d6c906e876d76b9e9c0526491d5d7472a13af (diff)
Remaining lexer combinators working
-rw-r--r--src/packrat-lexer-combinators.adb52
-rw-r--r--test/ratnest-tests.adb25
2 files changed, 61 insertions, 16 deletions
diff --git a/src/packrat-lexer-combinators.adb b/src/packrat-lexer-combinators.adb
index 6405efb..1090398 100644
--- a/src/packrat-lexer-combinators.adb
+++ b/src/packrat-lexer-combinators.adb
@@ -65,26 +65,23 @@ package body Packrat.Lexer.Combinators is
return Empty_Fail;
end if;
loop
+ exit when Position > Input'Last;
Temp := Param (Input, Position);
- exit when Temp.Status = Failure;
- if Temp.Status = Needs_More then
- Result.Status := Optional_More;
- exit;
- end if;
+ exit when Temp.Status = Failure or Temp.Status = Needs_More;
Result := Result.Join (Temp);
Counter := Counter + 1;
Position := Start + Result.Length;
- if Position > Input'Last then
- Result.Status := Optional_More;
- exit;
- end if;
end loop;
if Counter < Minimum then
- if Result.Status = Optional_More then
+ if Position > Input'Last or Temp.Status = Needs_More then
Result.Status := Needs_More;
else
Result.Status := Failure;
end if;
+ elsif Position > Input'Last or Temp.Status = Needs_More then
+ Result.Status := Optional_More;
+ else
+ Result.Status := Success;
end if;
return Result;
end Many;
@@ -93,9 +90,40 @@ package body Packrat.Lexer.Combinators is
function Many_Until
(Input : in Element_Array;
Start : in Positive)
- return Combinator_Result is
+ return Combinator_Result
+ is
+ Result : Combinator_Result := Create_Result (0, Success, Empty_Array);
+ Temp : Combinator_Result;
+ Position : Positive := Start;
+ Counter : Natural := 0;
begin
- return Empty_Fail;
+ if Start > Input'Last then
+ return Empty_Fail;
+ end if;
+ loop
+ exit when Position > Input'Last;
+ Temp := Param (Input, Position);
+ exit when Temp.Status = Failure or Temp.Status = Needs_More or Test (Input (Position));
+ Result := Result.Join (Temp);
+ Counter := Counter + 1;
+ Position := Start + Result.Length;
+ end loop;
+ if Counter < Minimum then
+ if Position > Input'Last or Temp.Status = Needs_More then
+ Result.Status := Needs_More;
+ else
+ Result.Status := Failure;
+ end if;
+ elsif Position > Input'Last then
+ Result.Status := Needs_More;
+ elsif Temp.Status = Needs_More and Test (Input (Position)) then
+ Result.Status := Optional_More;
+ elsif Test (Input (Position)) then
+ Result.Status := Success;
+ else
+ Result.Status := Failure;
+ end if;
+ return Result;
end Many_Until;
diff --git a/test/ratnest-tests.adb b/test/ratnest-tests.adb
index 0fac8cd..6f649d9 100644
--- a/test/ratnest-tests.adb
+++ b/test/ratnest-tests.adb
@@ -379,7 +379,17 @@ package body Ratnest.Tests is
function Many_0 is new Strombo.Many (Match_A);
function Many_4 is new Strombo.Many (Match_A, 4);
- Test_Str : String := "aaabbaaaaabaa";
+ function Match_B is new Strombo.Match ('b');
+ function Match_C is new Strombo.Match ('c');
+ function Seq_Abc is new Strombo.Sequence
+ ((Match_A'Unrestricted_Access,
+ Match_B'Unrestricted_Access,
+ Match_C'Unrestricted_Access));
+ function Many_Seq_0 is new Strombo.Many (Seq_Abc);
+ function Many_Seq_4 is new Strombo.Many (Seq_Abc, 4);
+
+ Test_Str : String := "aaabbaaaaabaa";
+ Test_Str2 : String := "aababcabcab";
Result1 : Slexy.Combinator_Result :=
Slexy.Create_Result (3, Packrat.Success, "aaa");
@@ -392,11 +402,18 @@ package body Ratnest.Tests is
Result5 : Slexy.Combinator_Result := Slexy.Empty_Fail;
Result6 : Slexy.Combinator_Result :=
Slexy.Create_Result (2, Packrat.Needs_More, "aa");
+ Result7 : Slexy.Combinator_Result :=
+ Slexy.Create_Result (0, Packrat.Success, "");
+ Result8 : Slexy.Combinator_Result :=
+ Slexy.Create_Result (6, Packrat.Optional_More, "abcabc");
+ Result9 : Slexy.Combinator_Result :=
+ Slexy.Create_Result (6, Packrat.Needs_More, "abcabc");
begin
if Many_0 (Test_Str, 1) /= Result1 or Many_4 (Test_Str, 1) /= Result4 or
- Many_4 (Test_Str, 6) /= Result3 or Many_0 (Test_Str, 4) /= Result5 or
+ Many_4 (Test_Str, 6) /= Result3 or Many_0 (Test_Str, 4) /= Result7 or
Many_0 (Test_Str, 12) /= Result2 or Many_4 (Test_Str, 12) /= Result6 or
- Many_0 (Test_Str, Test_Str'Last + 5) /= Result5
+ Many_0 (Test_Str, Test_Str'Last + 5) /= Result5 or
+ Many_Seq_0 (Test_Str2, 4) /= Result8 or Many_Seq_4 (Test_Str2, 4) /= Result9
then
return Fail;
end if;
@@ -418,7 +435,7 @@ package body Ratnest.Tests is
Result2 : Slexy.Combinator_Result :=
Slexy.Create_Result (3, Packrat.Success, "aaa");
Result3 : Slexy.Combinator_Result :=
- Slexy.Create_Result (3, Packrat.Optional_More, "aaa");
+ Slexy.Create_Result (3, Packrat.Needs_More, "aaa");
Result4 : Slexy.Combinator_Result := Slexy.Empty_Fail;
begin
if Many_Until_0 (Test_Str, 1) /= Result1 or