From a21cc8153592700ae7cb2cdfbb24b377e096a22a Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Fri, 4 Dec 2020 20:17:43 +1100 Subject: Scan/Parse functions are now packages, tests broken with linker errors --- src/packrat-lexers.adb | 456 ++++++++++++++++++++++++++----------------------- 1 file changed, 246 insertions(+), 210 deletions(-) (limited to 'src/packrat-lexers.adb') 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) -- cgit