summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2020-12-04 20:17:43 +1100
committerJed Barber <jjbarber@y7mail.com>2020-12-04 20:17:43 +1100
commita21cc8153592700ae7cb2cdfbb24b377e096a22a (patch)
tree9dec048f52576a9881241e509fee72f8b91ac090 /src
parent0abd0d9444164cbb85df0e5a50451b5f98fef3db (diff)
Scan/Parse functions are now packages, tests broken with linker errors
Diffstat (limited to 'src')
-rw-r--r--src/packrat-lexers.adb456
-rw-r--r--src/packrat-lexers.ads123
-rw-r--r--src/packrat-parsers.adb167
-rw-r--r--src/packrat-parsers.ads47
4 files changed, 449 insertions, 344 deletions
diff --git a/src/packrat-lexers.adb b/src/packrat-lexers.adb
index fc63e4a..830fdeb 100644
--- a/src/packrat-lexers.adb
+++ b/src/packrat-lexers.adb
@@ -25,97 +25,6 @@ package body Packrat.Lexers is
- function Stamp
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Component_Result
- is
- Current_Result : Combinator_Result :=
- Combo (Input, Context.Position);
- begin
- if Context.Status /= Success or Context.Position > Input'Last or
- Context.Empty_Labels.Contains (Label)
- then
- return Component_Failure;
- end if;
-
- if (Current_Result.Status = Needs_More and not Context.Allow_Incomplete) or
- Current_Result.Status = Failure
- then
- Context.Error_Labels.Append (Label);
- return Component_Failure;
- end if;
-
- if (Current_Result.Status = Optional_More and not Context.Allow_Incomplete) or
- Current_Result.Status = Success
- then
- Context.Result_So_Far.Append (Traits.Tokens.Create
- (Label,
- Context.Position + Context.Offset,
- Input (Context.Position .. Current_Result.Finish)));
- if Current_Result.Finish = 0 then
- Context.Empty_Labels.Insert (Label);
- else
- Context.Empty_Labels.Clear;
- Context.Position := Current_Result.Finish + 1;
- end if;
- else
- Context.Status := Current_Result.Status;
- Context.Pass_Forward.Replace_Element
- (Input (Context.Position .. Current_Result.Finish));
- Context.Empty_Labels.Clear;
- end if;
-
- Context.Error_Labels.Clear;
- return Component_Success;
- end Stamp;
-
-
- function Ignore
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Component_Result
- is
- Current_Result : Combinator_Result :=
- Combo (Input, Context.Position);
- begin
- if Context.Status /= Success or Context.Position > Input'Last or
- Context.Empty_Labels.Contains (Label)
- then
- return Component_Failure;
- end if;
-
- if (Current_Result.Status = Needs_More and not Context.Allow_Incomplete) or
- Current_Result.Status = Failure
- then
- Context.Error_Labels.Append (Label);
- return Component_Failure;
- end if;
-
- if (Current_Result.Status = Optional_More and not Context.Allow_Incomplete) or
- Current_Result.Status = Success
- then
- if Current_Result.Finish = 0 then
- Context.Empty_Labels.Insert (Label);
- else
- Context.Empty_Labels.Clear;
- Context.Position := Current_Result.Finish + 1;
- end if;
- else
- Context.Status := Current_Result.Status;
- Context.Pass_Forward.Replace_Element
- (Input (Context.Position .. Current_Result.Finish));
- Context.Empty_Labels.Clear;
- end if;
-
- Context.Error_Labels.Clear;
- return Component_Success;
- end Ignore;
-
-
-
-
-
procedure Tidy_Context
(Details : in out Lexer_Context;
Number_Comp : in Ada.Containers.Count_Type) is
@@ -208,142 +117,129 @@ package body Packrat.Lexers is
- function Scan
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array
- is
- Real_Input : Input_Holders.Holder;
- begin
- if not Context.Pass_Forward.Is_Empty then
- Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
- else
- Real_Input.Replace_Element (Input);
- end if;
+ package body Scan_Parts is
- Tidy_Context (Context, Components'Length);
- Context.Result_So_Far.Clear;
- Context.Allow_Incomplete := Input'Length > 0;
-
- while Context.Status = Success and Context.Position <= Real_Input.Element'Length loop
- Internal_Scan_Core (Real_Input.Element, Context, Components);
- end loop;
-
- return Token_Vector_To_Array (Context.Result_So_Far);
- end Scan;
+ Context : Lexer_Context := Empty_Context;
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array
+ is
+ Real_Input : Input_Holders.Holder;
+ begin
+ if not Context.Pass_Forward.Is_Empty then
+ Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
+ else
+ Real_Input.Replace_Element (Input);
+ end if;
+ Tidy_Context (Context, Components'Length);
+ Context.Result_So_Far.Clear;
+ Context.Allow_Incomplete := Input'Length > 0;
+ while Context.Status = Success and Context.Position <= Real_Input.Element'Length loop
+ Internal_Scan_Core (Real_Input.Element, Context, Components);
+ end loop;
+ return Token_Vector_To_Array (Context.Result_So_Far);
+ end Scan;
- function Scan_Only
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array
- is
- Real_Input : Input_Holders.Holder;
- begin
- if not Context.Pass_Forward.Is_Empty then
- Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
- else
- Real_Input.Replace_Element (Input);
- end if;
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
- Tidy_Context (Context, Components'Length);
- Context.Result_So_Far.Clear;
- Context.Allow_Incomplete := False;
+ end Scan_Parts;
- while Context.Status = Success and Context.Position <= Real_Input.Element'Length loop
- Internal_Scan_Core (Real_Input.Element, Context, Components);
- end loop;
- return Token_Vector_To_Array (Context.Result_So_Far);
- end Scan_Only;
+ package body Scan_Once is
+ Context : Lexer_Context := Empty_Context;
- function Scan_With
- (Input : in With_Input;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array
- is
- Real_Input : Input_Holders.Holder;
- Empty_Input : Boolean;
- begin
- Context.Result_So_Far.Clear;
- loop
- Real_Input.Replace_Element (Input.all);
- Empty_Input := Real_Input.Element'Length = 0;
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array
+ is
+ Real_Input : Input_Holders.Holder;
+ begin
if not Context.Pass_Forward.Is_Empty then
- Real_Input.Replace_Element
- (Slide (Context.Pass_Forward.Element) & Real_Input.Element);
+ Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
+ else
+ Real_Input.Replace_Element (Input);
end if;
-
Tidy_Context (Context, Components'Length);
- Context.Allow_Incomplete := not Empty_Input;
-
+ Context.Result_So_Far.Clear;
+ Context.Allow_Incomplete := False;
while Context.Status = Success and Context.Position <= Real_Input.Element'Length loop
Internal_Scan_Core (Real_Input.Element, Context, Components);
end loop;
+ return Token_Vector_To_Array (Context.Result_So_Far);
+ end Scan;
- if Empty_Input then
- exit;
- end if;
- end loop;
- return Token_Vector_To_Array (Context.Result_So_Far);
- end Scan_With;
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
+ end Scan_Once;
- procedure Scan_Set
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context;
- Output : out Traits.Tokens.Token_Array)
- is
- Real_Input : Input_Holders.Holder;
- begin
- if not Context.Pass_Forward.Is_Empty then
- Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
- else
- Real_Input.Replace_Element (Input);
- end if;
- Tidy_Context (Context, Components'Length);
- Context.Result_So_Far.Clear;
- Context.Allow_Incomplete := not (Input'Length = 0 or else Input (Input'First) = Pad_In);
+ package body Scan_With is
- while Context.Status = Success and then
- Integer (Context.Result_So_Far.Length) < Output'Length and then
- Context.Position <= Real_Input.Element'Length and then
- Real_Input.Element (Context.Position) /= Pad_In
- loop
- Internal_Scan_Core (Real_Input.Element, Context, Components);
- end loop;
+ Context : Lexer_Context := Empty_Context;
- if Integer (Context.Result_So_Far.Length) = Output'Length then
- Context.Pass_Forward.Replace_Element
- (Real_Input.Element (Context.Position .. Real_Input.Element'Last));
- end if;
- Token_Vector_To_Array (Context.Result_So_Far, Pad_Out, Output);
- end Scan_Set;
+ function Scan
+ (Input : in With_Input)
+ return Traits.Tokens.Token_Array
+ is
+ Real_Input : Input_Holders.Holder;
+ Empty_Input : Boolean;
+ begin
+ Context.Result_So_Far.Clear;
+ loop
+ Real_Input.Replace_Element (Input.all);
+ Empty_Input := Real_Input.Element'Length = 0;
+ if not Context.Pass_Forward.Is_Empty then
+ Real_Input.Replace_Element
+ (Slide (Context.Pass_Forward.Element) & Real_Input.Element);
+ end if;
+ Tidy_Context (Context, Components'Length);
+ Context.Allow_Incomplete := not Empty_Input;
+ while Context.Status = Success and
+ Context.Position <= Real_Input.Element'Length
+ loop
+ Internal_Scan_Core (Real_Input.Element, Context, Components);
+ end loop;
+ if Empty_Input then
+ exit;
+ end if;
+ end loop;
+ return Token_Vector_To_Array (Context.Result_So_Far);
+ end Scan;
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
- procedure Scan_Set_With
- (Input : in With_Input;
- Context : in out Lexer_Context;
- Output : out Traits.Tokens.Token_Array)
- is
- Real_Input : Input_Holders.Holder;
- Empty_Input : Boolean;
- begin
- Context.Result_So_Far.Clear;
- loop
- Real_Input.Replace_Element (Input.all);
- Empty_Input := Real_Input.Element'Length = 0 or else
- Real_Input.Element (Real_Input.Element'First) = Pad_In;
+ end Scan_With;
+
+
+ package body Scan_Set is
+
+ Context : Lexer_Context := Empty_Context;
+
+ procedure Scan
+ (Input : in Traits.Element_Array;
+ Output : out Traits.Tokens.Token_Array)
+ is
+ Real_Input : Input_Holders.Holder;
+ begin
if not Context.Pass_Forward.Is_Empty then
- Real_Input.Replace_Element
- (Slide (Context.Pass_Forward.Element) & Real_Input.Element);
+ Real_Input.Replace_Element (Slide (Context.Pass_Forward.Element) & Input);
+ else
+ Real_Input.Replace_Element (Input);
end if;
-
Tidy_Context (Context, Components'Length);
- Context.Allow_Incomplete := not Empty_Input;
-
+ Context.Result_So_Far.Clear;
+ Context.Allow_Incomplete := not (Input'Length = 0 or else Input (Input'First) = Pad_In);
while Context.Status = Success and then
Integer (Context.Result_So_Far.Length) < Output'Length and then
Context.Position <= Real_Input.Element'Length and then
@@ -351,24 +247,164 @@ package body Packrat.Lexers is
loop
Internal_Scan_Core (Real_Input.Element, Context, Components);
end loop;
-
- if Empty_Input then
- exit;
- end if;
-
if Integer (Context.Result_So_Far.Length) = Output'Length then
Context.Pass_Forward.Replace_Element
(Real_Input.Element (Context.Position .. Real_Input.Element'Last));
- exit;
end if;
- end loop;
- Token_Vector_To_Array (Context.Result_So_Far, Pad_Out, Output);
+ Token_Vector_To_Array (Context.Result_So_Far, Pad_Out, Output);
+ end Scan;
+
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
+
+ end Scan_Set;
+
+
+ package body Scan_Set_With is
+
+ Context : Lexer_Context := Empty_Context;
+
+ procedure Scan
+ (Input : in With_Input;
+ Output : out Traits.Tokens.Token_Array)
+ is
+ Real_Input : Input_Holders.Holder;
+ Empty_Input : Boolean;
+ begin
+ Context.Result_So_Far.Clear;
+ loop
+ Real_Input.Replace_Element (Input.all);
+ Empty_Input := Real_Input.Element'Length = 0 or else
+ Real_Input.Element (Real_Input.Element'First) = Pad_In;
+ if not Context.Pass_Forward.Is_Empty then
+ Real_Input.Replace_Element
+ (Slide (Context.Pass_Forward.Element) & Real_Input.Element);
+ end if;
+ Tidy_Context (Context, Components'Length);
+ Context.Allow_Incomplete := not Empty_Input;
+ while Context.Status = Success and then
+ Integer (Context.Result_So_Far.Length) < Output'Length and then
+ Context.Position <= Real_Input.Element'Length and then
+ Real_Input.Element (Context.Position) /= Pad_In
+ loop
+ Internal_Scan_Core (Real_Input.Element, Context, Components);
+ end loop;
+ if Empty_Input then
+ exit;
+ end if;
+ if Integer (Context.Result_So_Far.Length) = Output'Length then
+ Context.Pass_Forward.Replace_Element
+ (Real_Input.Element (Context.Position .. Real_Input.Element'Last));
+ exit;
+ end if;
+ end loop;
+ Token_Vector_To_Array (Context.Result_So_Far, Pad_Out, Output);
+ end Scan;
+
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
+
end Scan_Set_With;
+ function Stamp
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result
+ is
+ Current_Result : Combinator_Result :=
+ Combo (Input, Context.Position);
+ begin
+ if Context.Status /= Success or Context.Position > Input'Last or
+ Context.Empty_Labels.Contains (Label)
+ then
+ return Component_Failure;
+ end if;
+
+ if (Current_Result.Status = Needs_More and not Context.Allow_Incomplete) or
+ Current_Result.Status = Failure
+ then
+ Context.Error_Labels.Append (Label);
+ return Component_Failure;
+ end if;
+
+ if (Current_Result.Status = Optional_More and not Context.Allow_Incomplete) or
+ Current_Result.Status = Success
+ then
+ Context.Result_So_Far.Append (Traits.Tokens.Create
+ (Label,
+ Context.Position + Context.Offset,
+ Input (Context.Position .. Current_Result.Finish)));
+ if Current_Result.Finish = 0 then
+ Context.Empty_Labels.Insert (Label);
+ else
+ Context.Empty_Labels.Clear;
+ Context.Position := Current_Result.Finish + 1;
+ end if;
+ else
+ Context.Status := Current_Result.Status;
+ Context.Pass_Forward.Replace_Element
+ (Input (Context.Position .. Current_Result.Finish));
+ Context.Empty_Labels.Clear;
+ end if;
+
+ Context.Error_Labels.Clear;
+ return Component_Success;
+ end Stamp;
+
+
+ function Ignore
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result
+ is
+ Current_Result : Combinator_Result :=
+ Combo (Input, Context.Position);
+ begin
+ if Context.Status /= Success or Context.Position > Input'Last or
+ Context.Empty_Labels.Contains (Label)
+ then
+ return Component_Failure;
+ end if;
+
+ if (Current_Result.Status = Needs_More and not Context.Allow_Incomplete) or
+ Current_Result.Status = Failure
+ then
+ Context.Error_Labels.Append (Label);
+ return Component_Failure;
+ end if;
+
+ if (Current_Result.Status = Optional_More and not Context.Allow_Incomplete) or
+ Current_Result.Status = Success
+ then
+ if Current_Result.Finish = 0 then
+ Context.Empty_Labels.Insert (Label);
+ else
+ Context.Empty_Labels.Clear;
+ Context.Position := Current_Result.Finish + 1;
+ end if;
+ else
+ Context.Status := Current_Result.Status;
+ Context.Pass_Forward.Replace_Element
+ (Input (Context.Position .. Current_Result.Finish));
+ Context.Empty_Labels.Clear;
+ end if;
+
+ Context.Error_Labels.Clear;
+ return Component_Success;
+ end Ignore;
+
+
+
+
+
function Sequence
(Input : in Traits.Element_Array;
Start : in Positive)
diff --git a/src/packrat-lexers.ads b/src/packrat-lexers.ads
index 57fc462..68a01d0 100644
--- a/src/packrat-lexers.ads
+++ b/src/packrat-lexers.ads
@@ -17,6 +17,11 @@ generic
package Packrat.Lexers is
+ type Lexer_Context is private;
+
+
+
+
type Combinator_Result is private;
type Combinator is access function
@@ -29,13 +34,6 @@ package Packrat.Lexers is
- type Lexer_Context is private;
-
- Empty_Context : constant Lexer_Context;
-
-
-
-
type Component_Result is private;
type Component is access function
@@ -55,68 +53,97 @@ package Packrat.Lexers is
generic
- Label : in Traits.Label_Enum;
- with function Combo
- (Input : in Traits.Element_Array;
- Start : in Positive)
- return Combinator_Result;
- function Stamp
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Component_Result;
+ Components : in Component_Array;
+ package Scan_Parts is
- generic
- Label : in Traits.Label_Enum;
- with function Combo
- (Input : in Traits.Element_Array;
- Start : in Positive)
- return Combinator_Result;
- function Ignore
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Component_Result;
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array;
+ procedure Reset;
+ end Scan_Parts;
generic
Components : in Component_Array;
- function Scan
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array;
+ package Scan_Once is
+
+ function Scan
+ (Input : in Traits.Element_Array)
+ return Traits.Tokens.Token_Array;
+
+ procedure Reset;
+
+ end Scan_Once;
- generic
- Components : in Component_Array;
- function Scan_Only
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array;
generic
Components : in Component_Array;
- function Scan_With
- (Input : in With_Input;
- Context : in out Lexer_Context)
- return Traits.Tokens.Token_Array;
+ package Scan_With is
+
+ function Scan
+ (Input : in With_Input)
+ return Traits.Tokens.Token_Array;
+
+ procedure Reset;
+
+ end Scan_With;
+
generic
Components : in Component_Array;
Pad_In : in Traits.Element_Type;
Pad_Out : in Traits.Tokens.Token;
- procedure Scan_Set
- (Input : in Traits.Element_Array;
- Context : in out Lexer_Context;
- Output : out Traits.Tokens.Token_Array);
+ package Scan_Set is
+
+ procedure Scan
+ (Input : in Traits.Element_Array;
+ Output : out Traits.Tokens.Token_Array);
+
+ procedure Reset;
+
+ end Scan_Set;
+
generic
Components : in Component_Array;
Pad_In : in Traits.Element_Type;
Pad_Out : in Traits.Tokens.Token;
- procedure Scan_Set_With
- (Input : in With_Input;
- Context : in out Lexer_Context;
- Output : out Traits.Tokens.Token_Array);
+ package Scan_Set_With is
+
+ procedure Scan
+ (Input : in With_Input;
+ Output : out Traits.Tokens.Token_Array);
+
+ procedure Reset;
+
+ end Scan_Set_With;
+
+
+
+
+ generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+ function Stamp
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result;
+
+ generic
+ Label : in Traits.Label_Enum;
+ with function Combo
+ (Input : in Traits.Element_Array;
+ Start : in Positive)
+ return Combinator_Result;
+ function Ignore
+ (Input : in Traits.Element_Array;
+ Context : in out Lexer_Context)
+ return Component_Result;
diff --git a/src/packrat-parsers.adb b/src/packrat-parsers.adb
index df88e71..d854f73 100644
--- a/src/packrat-parsers.adb
+++ b/src/packrat-parsers.adb
@@ -416,82 +416,111 @@ package body Packrat.Parsers is
end Finish_Root;
- procedure Parse
- (Input : in Traits.Element_Array;
- Context : in out Parser_Context;
- Result : out Graphs.Parse_Graph) is
- begin
- Tidy_Context (Input, Context);
- Context.Allow_Incomplete := (Input'Length /= 0);
- declare
- use type Traits.Element_Array;
- Real_Input : Traits.Element_Array :=
- (if Context.Pass_Forward.Is_Empty
- then Slide (Input, Context.Current_Position)
- else Element (Context.Pass_Forward) & Input);
- Root_Result : Combinator_Result :=
- Root (Real_Input, Context, Context.Global_Start);
- begin
- if Root_Result.Status = Failure then
- raise Parser_Error with -Context.Error_String;
- end if;
- if Input'Length = 0 then
- Result := Finish_Root (Root_Result, Context);
- return;
- end if;
- if not Context.Needs_More.Is_Empty then
- Context.Current_Position := Context.Needs_More.First_Element;
- Context.Pass_Forward.Replace_Element
- (Real_Input (Context.Current_Position .. Real_Input'Last));
- else
- Context.Current_Position := Real_Input'Last + 1;
- Context.Pass_Forward.Clear;
- end if;
- end;
- end Parse;
+ package body Parse_Parts is
+ Context : Parser_Context := Empty_Context;
- function Parse_Only
- (Input : in Traits.Element_Array;
- Context : in out Parser_Context)
- return Graphs.Parse_Graph is
- begin
- Tidy_Context (Input, Context);
- Context.Allow_Incomplete := False;
- declare
- use type Traits.Element_Array;
- Real_Input : Traits.Element_Array :=
- (if Context.Pass_Forward.Is_Empty
- then Slide (Input, Context.Current_Position)
- else Element (Context.Pass_Forward) & Input);
- Root_Result : Combinator_Result :=
- Root (Real_Input, Context, Context.Global_Start);
+ procedure Parse
+ (Input : in Traits.Element_Array;
+ Result : out Graphs.Parse_Graph) is
begin
- if Root_Result.Status /= Success then
- raise Parser_Error with -Context.Error_String;
- end if;
- return Finish_Root (Root_Result, Context);
- end;
- end Parse_Only;
+ Tidy_Context (Input, Context);
+ Context.Allow_Incomplete := (Input'Length /= 0);
+ declare
+ use type Traits.Element_Array;
+ Real_Input : Traits.Element_Array :=
+ (if Context.Pass_Forward.Is_Empty
+ then Slide (Input, Context.Current_Position)
+ else Element (Context.Pass_Forward) & Input);
+ Root_Result : Combinator_Result :=
+ Root (Real_Input, Context, Context.Global_Start);
+ begin
+ if Root_Result.Status = Failure then
+ raise Parser_Error with -Context.Error_String;
+ end if;
+ if Input'Length = 0 then
+ Result := Finish_Root (Root_Result, Context);
+ return;
+ end if;
+ if not Context.Needs_More.Is_Empty then
+ Context.Current_Position := Context.Needs_More.First_Element;
+ Context.Pass_Forward.Replace_Element
+ (Real_Input (Context.Current_Position .. Real_Input'Last));
+ else
+ Context.Current_Position := Real_Input'Last + 1;
+ Context.Pass_Forward.Clear;
+ end if;
+ end;
+ end Parse;
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
- function Parse_With
- (Input : in With_Input;
- Context : in out Parser_Context)
- return Graphs.Parse_Graph
- is
- procedure My_Parse is new Parse (Root);
- Result : Graphs.Parse_Graph;
- begin
- loop
+ end Parse_Parts;
+
+
+ package body Parse_Once is
+
+ Context : Parser_Context := Empty_Context;
+
+ function Parse
+ (Input : in Traits.Element_Array)
+ return Graphs.Parse_Graph is
+ begin
+ Tidy_Context (Input, Context);
+ Context.Allow_Incomplete := False;
declare
- Next_Input : Traits.Element_Array := Input.all;
+ use type Traits.Element_Array;
+ Real_Input : Traits.Element_Array :=
+ (if Context.Pass_Forward.Is_Empty
+ then Slide (Input, Context.Current_Position)
+ else Element (Context.Pass_Forward) & Input);
+ Root_Result : Combinator_Result :=
+ Root (Real_Input, Context, Context.Global_Start);
begin
- My_Parse (Next_Input, Context, Result);
- exit when Next_Input'Length = 0;
+ if Root_Result.Status /= Success then
+ raise Parser_Error with -Context.Error_String;
+ end if;
+ return Finish_Root (Root_Result, Context);
end;
- end loop;
- return Result;
+ end Parse;
+
+ procedure Reset is
+ begin
+ Context := Empty_Context;
+ end Reset;
+
+ end Parse_Once;
+
+
+ package body Parse_With is
+
+ package My_Parse is new Parse_Parts (Root);
+
+ function Parse
+ (Input : in With_Input)
+ return Graphs.Parse_Graph
+ is
+ Result : Graphs.Parse_Graph;
+ begin
+ loop
+ declare
+ Next_Input : Traits.Element_Array := Input.all;
+ begin
+ My_Parse.Parse (Next_Input, Result);
+ exit when Next_Input'Length = 0;
+ end;
+ end loop;
+ return Result;
+ end Parse;
+
+ procedure Reset is
+ begin
+ My_Parse.Reset;
+ end Reset;
+
end Parse_With;
@@ -584,6 +613,8 @@ package body Packrat.Parsers is
package body Redirect is
+ Combo : Combinator := null;
+
procedure Set
(Target : in Combinator) is
begin
diff --git a/src/packrat-parsers.ads b/src/packrat-parsers.ads
index 8d0ba68..93d06dd 100644
--- a/src/packrat-parsers.ads
+++ b/src/packrat-parsers.ads
@@ -24,8 +24,6 @@ package Packrat.Parsers is
type Parser_Context is private;
- Empty_Context : constant Parser_Context;
-
@@ -54,10 +52,16 @@ package Packrat.Parsers is
Context : in out Parser_Context;
Start : in Positive)
return Combinator_Result;
- procedure Parse
- (Input : in Traits.Element_Array;
- Context : in out Parser_Context;
- Result : out Graphs.Parse_Graph);
+ package Parse_Parts is
+
+ procedure Parse
+ (Input : in Traits.Element_Array;
+ Result : out Graphs.Parse_Graph);
+
+ procedure Reset;
+
+ end Parse_Parts;
+
generic
with function Root
@@ -65,10 +69,16 @@ package Packrat.Parsers is
Context : in out Parser_Context;
Start : in Positive)
return Combinator_Result;
- function Parse_Only
- (Input : in Traits.Element_Array;
- Context : in out Parser_Context)
- return Graphs.Parse_Graph;
+ package Parse_Once is
+
+ function Parse
+ (Input : in Traits.Element_Array)
+ return Graphs.Parse_Graph;
+
+ procedure Reset;
+
+ end Parse_Once;
+
generic
with function Root
@@ -76,10 +86,15 @@ package Packrat.Parsers is
Context : in out Parser_Context;
Start : in Positive)
return Combinator_Result;
- function Parse_With
- (Input : in With_Input;
- Context : in out Parser_Context)
- return Graphs.Parse_Graph;
+ package Parse_With is
+
+ function Parse
+ (Input : in With_Input)
+ return Graphs.Parse_Graph;
+
+ procedure Reset;
+
+ end Parse_With;
@@ -125,10 +140,6 @@ package Packrat.Parsers is
Start : in Positive)
return Combinator_Result;
- private
-
- Combo : Combinator := null;
-
end Redirect;