summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2021-01-21 16:33:47 +1100
committerJed Barber <jjbarber@y7mail.com>2021-01-21 16:33:47 +1100
commit30d59f09f6908aa0de2ec3a58a0736c8030ffda5 (patch)
treeffbca1ff15ffe02de67374687b7210131cace28e /src
parentd089edbb61f6bf6b52bc74f7f03f909b8b33b670 (diff)
Piecewise parsing fixed, unit tested
Diffstat (limited to 'src')
-rw-r--r--src/packrat-errors.adb24
-rw-r--r--src/packrat-errors.ads5
-rw-r--r--src/packrat-parsers.adb94
3 files changed, 103 insertions, 20 deletions
diff --git a/src/packrat-errors.adb b/src/packrat-errors.adb
index 3f7c38f..0122b7d 100644
--- a/src/packrat-errors.adb
+++ b/src/packrat-errors.adb
@@ -313,6 +313,30 @@ package body Packrat.Errors is
end Decode;
+
+
+
+ function Equivalent
+ (Left, Right : in Error_Info_Array)
+ return Boolean
+ is
+ Marked : array (Left'Range) of Boolean := (others => False);
+ begin
+ if Left'Length /= Right'Length then
+ return False;
+ end if;
+ for L_Index in Left'Range loop
+ for R of Right loop
+ if Left (L_Index) = R and not Marked (L_Index) then
+ Marked (L_Index) := True;
+ exit;
+ end if;
+ end loop;
+ end loop;
+ return (for all M of Marked => M = True);
+ end Equivalent;
+
+
end Packrat.Errors;
diff --git a/src/packrat-errors.ads b/src/packrat-errors.ads
index 50fa966..d3b38c3 100644
--- a/src/packrat-errors.ads
+++ b/src/packrat-errors.ads
@@ -79,6 +79,11 @@ package Packrat.Errors is
return Error_Info_Array;
+ function Equivalent
+ (Left, Right : in Error_Info_Array)
+ return Boolean;
+
+
end Packrat.Errors;
diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb
index abb2736..26d5343 100644
--- a/src/packrat-parsers.adb
+++ b/src/packrat-parsers.adb
@@ -313,7 +313,6 @@ package body Packrat.Parsers is
Target.Results.Union (Add.Results);
Target.Status := Add.Status;
when Needs_More =>
- null;
Target.Status := Add.Status;
when Failure =>
null;
@@ -343,6 +342,9 @@ package body Packrat.Parsers is
Salt, Temp : Combinator_Result;
Adjust : Result_Sets.Set;
begin
+ if From.Status = Failure or From.Status = Needs_More then
+ return From;
+ end if;
Salt.Curtails := From.Curtails;
for R of From.Results loop
Temp := Next (Input, Context, R.Finish + 1);
@@ -356,6 +358,9 @@ package body Packrat.Parsers is
Temp.Results := Adjust;
Merge (Salt, Temp);
end loop;
+ if Salt.Status = Failure and From.Status = Optional_More then
+ Salt.Status := Needs_More;
+ end if;
return Salt;
end Continue;
@@ -739,7 +744,8 @@ package body Packrat.Parsers is
end if;
Salt := Params (Params'First) (Input, Context, Start);
for I in Integer range Params'First + 1 .. Params'Last loop
- exit when Salt.Status = Failure;
+ exit when Salt.Status = Failure or
+ (Context.Allow_Incomplete and Salt.Status = Needs_More);
declare
function Cont_Param is new Continue (Params (I).all);
begin
@@ -773,6 +779,7 @@ package body Packrat.Parsers is
begin
Salt := Part_One (Input, Context, Start);
Salt := Cont_Param (Salt, Input, Context);
+ Complete_Status (Salt, Context.Allow_Incomplete);
return Salt;
end Actual;
function Memo is new Memoize (To_Key (Start, Sequence_2'Access), Actual);
@@ -816,11 +823,14 @@ package body Packrat.Parsers is
is
function Actual
(Context : in out Parser_Context)
- return Combinator_Result is
+ return Combinator_Result
+ is
+ Salt : Combinator_Result;
begin
- return Merge
- (Choice_One (Input, Context, Start),
- Choice_Two (Input, Context, Start));
+ Merge (Salt, Choice_One (Input, Context, Start));
+ Merge (Salt, Choice_Two (Input, Context, Start));
+ Complete_Status (Salt, Context.Allow_Incomplete);
+ return Salt;
end Actual;
function Memo is new Memoize (To_Key (Start, Choice_2'Access), Actual);
function Curt is new Curtailment (To_Key (Start, Choice_2'Access), Input, Memo);
@@ -1128,7 +1138,11 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
Salt : Combinator_Result;
begin
- if Start <= Input'Last and then Test (Input (Start)) then
+ if Start > Input'Last then
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ elsif Test (Input (Start)) then
Part.Finish := Start;
Part.Value := Elem_Holds.To_Holder (Input (Start .. Start));
Salt.Results.Include (Part);
@@ -1155,7 +1169,11 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
Salt : Combinator_Result;
begin
- if Start <= Input'Last and then Test (Change (Input (Start))) then
+ if Start > Input'Last then
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ elsif Test (Change (Input (Start))) then
Part.Finish := Start;
Part.Value := Elem_Holds.To_Holder (Input (Start .. Start));
Salt.Results.Include (Part);
@@ -1183,7 +1201,11 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
Salt : Combinator_Result;
begin
- if Start <= Input'Last and then Input (Start) = Item then
+ if Start > Input'Last then
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ elsif Input (Start) = Item then
Part.Finish := Start;
Part.Value := Elem_Holds.To_Holder (Input (Start .. Start));
Salt.Results.Include (Part);
@@ -1211,7 +1233,11 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
Salt : Combinator_Result;
begin
- if Start <= Input'Last and then Change (Input (Start)) = Item then
+ if Start > Input'Last then
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ elsif Change (Input (Start)) = Item then
Part.Finish := Start;
Part.Value := Elem_Holds.To_Holder (Input (Start .. Start));
Salt.Results.Include (Part);
@@ -1239,7 +1265,11 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
begin
if Start > Input'Last then
- return Salt : Combinator_Result;
+ return Salt : Combinator_Result do
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ end return;
elsif Items'Length = 0 then
return Empty (Input, Context, Start);
end if;
@@ -1280,10 +1310,9 @@ package body Packrat.Parsers is
is
Part : Combo_Result_Part;
begin
- if Start > Input'Last then
- return Salt : Combinator_Result;
- end if;
- if Input'Last - Start < Number - 1 then
+ if Start > Input'Last or else
+ Input'Last - Start < Number - 1
+ then
return Salt : Combinator_Result do
if Context.Allow_Incomplete then
Salt.Status := Needs_More;
@@ -1316,8 +1345,14 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
My_Finish : Positive := Start;
begin
- if Start > Input'Last or else not Test (Input (Start)) then
- return Empty_Fail;
+ if Start > Input'Last then
+ return Salt : Combinator_Result do
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ end return;
+ elsif not Test (Input (Start)) then
+ return Salt : Combinator_Result;
end if;
while My_Finish <= Input'Last and then Test (Input (My_Finish)) loop
My_Finish := My_Finish + 1;
@@ -1350,8 +1385,14 @@ package body Packrat.Parsers is
Part : Combo_Result_Part;
My_Finish : Positive := Start;
begin
- if Start > Input'Last or else Test (Input (Start)) then
- return Empty_Fail;
+ if Start > Input'Last then
+ return Salt : Combinator_Result do
+ if Context.Allow_Incomplete then
+ Salt.Status := Needs_More;
+ end if;
+ end return;
+ elsif Test (Input (Start)) then
+ return Salt : Combinator_Result;
end if;
while My_Finish <= Input'Last and then not Test (Input (My_Finish)) loop
My_Finish := My_Finish + 1;
@@ -1405,6 +1446,13 @@ package body Packrat.Parsers is
end if;
end loop;
Salt.Results.Assign (Adjust);
+ if Salt.Results.Is_Empty then
+ if Salt.Status = Success then
+ Salt.Status := Failure;
+ elsif Salt.Status = Optional_More then
+ Salt.Status := Needs_More;
+ end if;
+ end if;
return Salt;
end Not_Empty;
@@ -1416,7 +1464,13 @@ package body Packrat.Parsers is
return Combinator_Result is
begin
if Start > Input'Last then
- return Empty (Input, Context, Start);
+ if Context.Allow_Incomplete then
+ return Salt : Combinator_Result do
+ Salt.Status := Needs_More;
+ end return;
+ else
+ return Empty (Input, Context, Start);
+ end if;
else
return Salt : Combinator_Result;
end if;