diff options
| author | Jed Barber <jjbarber@y7mail.com> | 2020-12-04 20:17:43 +1100 | 
|---|---|---|
| committer | Jed Barber <jjbarber@y7mail.com> | 2020-12-04 20:17:43 +1100 | 
| commit | a21cc8153592700ae7cb2cdfbb24b377e096a22a (patch) | |
| tree | 9dec048f52576a9881241e509fee72f8b91ac090 /src/packrat-lexers.adb | |
| parent | 0abd0d9444164cbb85df0e5a50451b5f98fef3db (diff) | |
Scan/Parse functions are now packages, tests broken with linker errors
Diffstat (limited to 'src/packrat-lexers.adb')
| -rw-r--r-- | src/packrat-lexers.adb | 456 | 
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)  | 
