separate (Find_Unit.Build_Ada_Compilation_Unit)
procedure Function_Body_Or_Stub (Current_Unit : in out
                                    Compilation_Unit.Ada_Compilation_Unit) is
    --==============================================================
    -- This procedure builds the next part of the grammar for an   =
    -- Ada compilation unit. Based on the next token, we will      =
    -- complete different productions. At present, we are          =
    -- parsing either a Function body, or a generic Function       =
    -- instantiation.. If the keyword 'SEPARATE' is found, then    =
    -- parse a function body stub, else parse a funciton body.     =
    -- If any errors are found, the the exception                  =
    -- Build_Syntax_Error will be raised.                          =
    -- Grammar :                                                   =
    --    <Function_Body_Or_Stub> =                                =
    --  * { <Declaration>} <Begin_Statement> <Function_End_Unit>|  =
    --         'SEPARATE' ';'                                      =
    --                                                             =
    -- Written  by  GER  with  help  from  b2  and  JM             =
    -- May 1985  EVB Software Engineering Inc.                     =
    --==============================================================

    Begin_Found : Boolean := False;
    -- Set to true when 'begin' is found
    Current_Token : Token_Package.Token;
    -- The current token being processed
    Peek_Token : Token_Package.Token;
    -- A future token to be used later

begin
    -- Function_Body_Or_Stub

    -- Set the peek token back to the beginning

    Token_Package.Set_Peek_Back;

    -- Peek at the next token to see if it is 'NEW' or 'SEPARATE'

    Peek_Next_Significant_Token (Significant_Token => Peek_Token);

    case Token_Package.Value_Of (Peek_Token) is
        when Token_Package.Separate_Token =>

            -- Parse a subprogram body stub
            -- Get the keyword 'Separate' followed by a ';'

            Get_Next_Significant_Token (Significant_Token => Current_Token,
                                        Current_Unit => Current_Unit);
            Compilation_Unit.Add_Token_To_Compilation_Unit
               (Token_To_Add => Current_Token, Unit_To_Add_To => Current_Unit);

            Get_Next_Significant_Token (Significant_Token => Current_Token,
                                        Current_Unit => Current_Unit);

            if "/=" (Token_Package.Value_Of (Current_Token),
                     Token_Package.Semicolon_Token) then
                raise Build_Syntax_Error;
            else
                -- Found the end of the funciton body stub
                Compilation_Unit.Add_Token_To_Compilation_Unit
                   (Token_To_Add => Current_Token,
                    Unit_To_Add_To => Current_Unit);
            end if;

        when others =>

            -- Parse a funciton body
            -- Look for nested compilation units followed
            -- by the end of the subprogram body

            Look_For_Nested_Compilation_Units:
                loop

                    case Token_Package.Value_Of (Peek_Token) is
                        when Token_Package.Package_Token |
                             Token_Package.Procedure_Token |
                             Token_Package.Function_Token |
                             Token_Package.Task_Token |
                             Token_Package.Generic_Token =>

                            -- Parse a nested compilation unit ?

                            Declaration (Current_Unit => Current_Unit);
                        when Token_Package.Begin_Token =>

                            -- We've found the beginning of the statements

                            Begin_Found := True;

                        when others =>

                            -- Not a nested compilation unit or the beginning
                            -- of statements

                            Get_Next_Significant_Token
                               (Significant_Token => Current_Token,
                                Current_Unit => Current_Unit);

                            if Token_Package.Class_Of (Current_Token) =
                               Token_Package.End_Of_File then
                                raise Build_Syntax_Error;
                            else
                                -- Not the end of file yet
                                Compilation_Unit.Add_Token_To_Compilation_Unit
                                   (Token_To_Add => Current_Token,
                                    Unit_To_Add_To => Current_Unit);
                            end if;

                    end case;

                    exit Look_For_Nested_Compilation_Units when Begin_Found;

                    -- Peek at the next token looking for nested
                    -- compilation units or 'Begin'

                    Peek_Next_Significant_Token
                       (Significant_Token => Peek_Token);
                end loop Look_For_Nested_Compilation_Units;

            Begin_Statement (Current_Unit => Current_Unit);
            Function_End_Unit (Current_Unit => Current_Unit);

    end case;

end Function_Body_Or_Stub;