summaryrefslogtreecommitdiff
path: root/src/packrat-lexers.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/packrat-lexers.adb')
-rw-r--r--src/packrat-lexers.adb456
1 files changed, 246 insertions, 210 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)