separate (Compilation_Unit.Produce_Metrics)
procedure Constant_Declaration
             (Current_Compilation_Unit : in out Ada_Compilation_Unit;
              Program_Unit : in Program_Unit_State_Machine;
              Halstead : in Halstead_State_Machine;
              Loc : in Loc_State_Machine;
              Mccabe : in Mccabe_State_Machine) is


    --=======================================================================
    -- Constant_Declaration ::=
    --   "CONSTANT"
    --** changed 11/20/85 by J. Margono
    --** reason: "Some_Constant : constant Some_Type := Some_Expression"
    --**         was not handled correctly (i.e., raised Syntax_Error)
    --   ( ( Subtype_Indication | Array_Type_Definition ) [ ":=" Expression ]
    --     | ":=" Expression
    --   )
    --=======================================================================

    Current_Token : Token_Package.Token;
    Peek_Ahead_Token : Token_Package.Token;

begin
    -- Constant_Declaration

    Get_Next_Token (Out_Token => Current_Token,
                    From => Current_Compilation_Unit,
                    Current_Loc => Loc);

    if "/=" (Token_Package.Value_Of (Current_Token),
             Token_Package.Constant_Token) then
        raise Syntax_Error;
    end if;

    -- increment Halstead CONSTANT operator count
    Halstead.Store_Operator ((Kind => Halstead_Operator.Constant_Halstead));

    --** the following change is based on the new production above

    Peek_Ahead_Token := Peek (From => Current_Compilation_Unit);
    case Token_Package.Class_Of (Peek_Ahead_Token) is

        when Token_Package.Keyword | Token_Package.Identifier =>

            if Token_Package.Class_Of (Peek_Ahead_Token) =
               Token_Package.Identifier then

                Subtype_Indication
                   (Current_Compilation_Unit => Current_Compilation_Unit,
                    Program_Unit => Program_Unit,
                    Halstead => Halstead,
                    Loc => Loc,
                    Mccabe => Mccabe);

            elsif Token_Package.Value_Of (Peek_Ahead_Token) =
                  Token_Package.Array_Token then

                -- token class must be KEYWORD
                Array_Type_Definition
                   (Current_Compilation_Unit => Current_Compilation_Unit,
                    Program_Unit => Program_Unit,
                    Halstead => Halstead,
                    Loc => Loc,
                    Mccabe => Mccabe);
            else

                raise Syntax_Error;

            end if;

            -- find out whether the next token is ":=" or not
            if Token_Package.Value_Of (Peek
                                          (From => Current_Compilation_Unit)) =
               Token_Package.Assignment_Token then

                Get_Next_Token (Out_Token => Current_Token,
                                From => Current_Compilation_Unit,
                                Current_Loc => Loc);

                -- increment Halstead ASSIGNMENT operator count
                Halstead.Store_Operator
                   ((Kind => Halstead_Operator.Assignment_Halstead));

                -- until ";" is found
                Expression
                   (Current_Compilation_Unit => Current_Compilation_Unit,
                    Program_Unit => Program_Unit,
                    Halstead => Halstead,
                    Loc => Loc,
                    Mccabe => Mccabe,
                    Terminate_Tokens =>
                       Set_Of_Tokens'(1 => Token_Package.Semicolon_Token));

            end if;

        when Token_Package.Punctuation =>

            if Token_Package.Value_Of (Peek_Ahead_Token) =
               Token_Package.Assignment_Token then

                Get_Next_Token (Out_Token => Current_Token,
                                From => Current_Compilation_Unit,
                                Current_Loc => Loc);

                -- increment Halstead ASSIGNMENT operator count
                Halstead.Store_Operator
                   ((Kind => Halstead_Operator.Assignment_Halstead));

                -- until ";" is found
                Expression
                   (Current_Compilation_Unit => Current_Compilation_Unit,
                    Program_Unit => Program_Unit,
                    Halstead => Halstead,
                    Loc => Loc,
                    Mccabe => Mccabe,
                    Terminate_Tokens =>
                       Set_Of_Tokens'(1 => Token_Package.Semicolon_Token));

            else

                raise Syntax_Error;

            end if;

        when others =>
            raise Syntax_Error;

    end case;

end Constant_Declaration;