summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2020-12-12 17:12:21 +1100
committerJed Barber <jjbarber@y7mail.com>2020-12-12 17:12:21 +1100
commit8834bc154280e443aeac618eb433e365d82253c6 (patch)
tree099d74110f4b2ade9ff813c59d7e2b5570732ae4
parent2adeae8eb1bc8437b392bed07f1858363f95ab8a (diff)
Duplicate subgroup bug fixed, finally
-rw-r--r--src/packrat-parse_graphs.adb30
-rw-r--r--src/packrat-parse_graphs.ads6
-rw-r--r--src/packrat-parsers.adb1
-rw-r--r--test/rat_tests-parse_graphs.adb4
4 files changed, 34 insertions, 7 deletions
diff --git a/src/packrat-parse_graphs.adb b/src/packrat-parse_graphs.adb
index 434c0a0..49ca752 100644
--- a/src/packrat-parse_graphs.adb
+++ b/src/packrat-parse_graphs.adb
@@ -288,21 +288,34 @@ package body Packrat.Parse_Graphs is
function Contains
(Container : in Parse_Graph;
Grouping : in Token_Group)
+ return Boolean is
+ begin
+ return Container.Contains (Grouping.Parent, Elements (Grouping));
+ end Contains;
+
+
+ function Contains
+ (Container : in Parse_Graph;
+ Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
return Boolean
is
Groups : Group_ID_Vectors.Vector;
Next_ID : Group_ID_Type;
Parent_Node : Node_ID_Type;
begin
- if not Container.Contains (Grouping.Parent) then
+ if not Container.Contains (Parent.Token) then
return False;
end if;
- for Fin_Token of Elements (Grouping) loop
- if not Container.Contains (Fin_Token) then
+ for Fin_Token of Subtokens loop
+ if not Container.Contains (Fin_Token.Token) then
return False;
end if;
end loop;
- Parent_Node := Container.Label_Map.Element (Grouping.Parent.Token);
+ if not Valid_Starts_Finishes (Parent, Subtokens) then
+ return False;
+ end if;
+ Parent_Node := Container.Label_Map.Element (Parent.Token);
for Edge of Container.Internal_Graph.Outbound (Parent_Node) loop
Next_ID := Container.Internal_Graph.Label (Edge).Group_ID;
if not Groups.Contains (Next_ID) then
@@ -310,12 +323,12 @@ package body Packrat.Parse_Graphs is
end if;
end loop;
return (for some ID of Groups =>
- (for all Sub of Elements (Grouping) =>
+ (for all Sub of Subtokens =>
(for some Edge of Container.Internal_Graph.Between
(Parent_Node, Container.Label_Map.Element (Sub.Token)) =>
Container.Internal_Graph.Label (Edge) =
- (Group_ID => ID,
- Group_Finish => Finish (Grouping),
+ (Group_ID => ID,
+ Group_Finish => Parent.Finish,
Subnode_Finish => Sub.Finish))));
end Contains;
@@ -540,6 +553,9 @@ package body Packrat.Parse_Graphs is
New_Edge : Base.Edge_Type;
New_Label : Edge_Label_Type;
begin
+ if Container.Contains (Parent, Subtokens) then
+ return;
+ end if;
Container.Include (Parent.Token);
for Sub of Subtokens loop
Container.Include (Sub.Token);
diff --git a/src/packrat-parse_graphs.ads b/src/packrat-parse_graphs.ads
index 7d14652..e13bfc7 100644
--- a/src/packrat-parse_graphs.ads
+++ b/src/packrat-parse_graphs.ads
@@ -83,6 +83,12 @@ package Packrat.Parse_Graphs is
Grouping : in Token_Group)
return Boolean;
+ function Contains
+ (Container : in Parse_Graph;
+ Parent : in Traits.Tokens.Finished_Token_Type;
+ Subtokens : in Traits.Tokens.Finished_Token_Array)
+ return Boolean;
+
function Reachable
(Container : in Parse_Graph;
Position : in Traits.Tokens.Finished_Token_Type)
diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb
index 63dcb00..eba9e20 100644
--- a/src/packrat-parsers.adb
+++ b/src/packrat-parsers.adb
@@ -563,6 +563,7 @@ package body Packrat.Parsers is
Ada.Strings.Unbounded.Append
(Context.Error_String,
Packrat.Errors.Encode (Traits.Label_Enum'Image (Label), Start));
+ return Salt;
else
Context.Error_String := +"";
end if;
diff --git a/test/rat_tests-parse_graphs.adb b/test/rat_tests-parse_graphs.adb
index 06f977b..878bee0 100644
--- a/test/rat_tests-parse_graphs.adb
+++ b/test/rat_tests-parse_graphs.adb
@@ -195,6 +195,7 @@ package body Rat_Tests.Parse_Graphs is
+ -- Should probably add tests for this on incomplete graphs at some point
function Contains_Check
return Test_Result
is
@@ -223,6 +224,9 @@ package body Rat_Tests.Parse_Graphs is
then
return Fail;
end if;
+ if not Paper_Graph.Contains ((NP_1, 1), (1 => (Noun_1, 1))) then
+ return Fail;
+ end if;
return Pass;
end Contains_Check;