Справочник по Ada (Ada 2022)
10.1.1 Модули компиляции — библиотечные модули
Элемент library_item — это модуль компиляции, являющийся объявлением, телом или переименованием библиотечного модуля. Каждый библиотечный модуль (кроме Standard) имеет родительский модуль, который является библиотечным пакетом или обобщённым библиотечным пакетом. Библиотечный модуль является дочерним элементом своего родительского модуля. Корневые библиотечные модули являются дочерними элементами предопределённого библиотечного пакета Standard.
Синтаксис
library_item ::= [private] library_unit_declaration
| library_unit_body
| [private] library_unit_renaming_declaration
| library_unit_body
| [private] library_unit_renaming_declaration
library_unit_declaration ::=
subprogram_declaration | package_declaration
| generic_declaration | generic_instantiation
subprogram_declaration | package_declaration
| generic_declaration | generic_instantiation
library_unit_renaming_declaration ::=
package_renaming_declaration
| generic_renaming_declaration
| subprogram_renaming_declaration
package_renaming_declaration
| generic_renaming_declaration
| subprogram_renaming_declaration
Индикатор overriding_indicator не разрешается в subprogram_declaration, generic_instantiation или subprogram_renaming_declaration, которые объявляют библиотечный модуль.
Библиотечный модуль — это модуль программы, объявленный с помощью library_item. Когда модуль программы является библиотечным модулем, используется префикс «библиотечный» (или «обобщённый библиотечный», если обобщённый), а также для его объявления и тела, как в «библиотечная процедура», «библиотечный package_body» или «обобщённый библиотечный пакет». Термин модуль компиляции используется для обозначения compilation_unit. Когда смысл понятен из контекста, термин также используется для обозначения library_item модуля компиляции или для proper_body подмодуля subunit (то есть модуль компиляции без context_clause и separate (parent_unit_name)).
Родительское объявление элемента library_item (и библиотечного модуля) — это объявление, обозначаемое parent_unit_name, если таковое имеется, в defining_program_unit_name элемента library_item. Если parent_unit_name отсутствует, родительское объявление — это объявление Standard, элемент library_item является корневым, и библиотечный модуль (переименования) является корневым библиотечным модулем (переименованием). У объявления и тела самого Standard нет родительского объявления. Родительский модуль элемента library_item или библиотечного модуля — это библиотечный модуль, объявленный его родительским объявлением.
Дочерние элементы библиотечного модуля находятся непосредственно внутри области объявления объявления библиотечного модуля. Предки библиотечного модуля — это сам модуль, его родитель, родитель родителя и так далее. (Standard является предком каждого библиотечного модуля.) Потомковый отношение является обратным отношению предка.
Объявление library_unit_declaration или library_unit_renaming_declaration является частным, если объявление непосредственно предшествует зарезервированному слову private; в противном случае оно общедоступное. Библиотечный модуль является частным или общедоступным в соответствии со своим объявлением. Общедоступные потомки библиотечного модуля — это сам библиотечный модуль и общедоступные потомки его общедоступных дочерних элементов. Остальные потомки являются частными потомками.
Для каждого библиотечного объявления package_declaration в среде существует неявное объявление ограниченного представления этого библиотечного пакета. Ограниченное представление пакета содержит:
- Для каждого package_declaration, встречающегося непосредственно в видимой части, объявление ограниченного представления этого пакета с тем же defining_program_unit_name.
- Для каждого type_declaration, встречающегося непосредственно в видимой части, который не является incomplete_type_declaration, неполное представление типа без discriminant_part; если type_declaration помечен, то представлением является помеченное неполное представление.
Ограниченное представление библиотечного объявления package_declaration является частным, если это библиотечное объявление package_declaration непосредственно предшествует зарезервированному слову private.
Нет синтаксиса для объявления ограниченных представлений пакетов, так как они всегда неявные. Неявное объявление ограниченного представления библиотечного пакета не является объявлением библиотечного модуля (библиотечное package_declaration — это он); тем не менее, это library_item. Неявное объявление ограниченного представления библиотечного пакета образует (неявной) модуль компиляции, context_clause которого пустой.
Библиотечное объявление package_declaration является завершением объявления его ограниченного представления.
Правила легальности
Родительский модуль library_item должен быть библиотечным пакетом или обобщённым библиотечным пакетом.
Если defining_program_unit_name данного объявления или тела имеет parent_unit_name, то данное объявление или тело должно быть library_item. Тело модуля программы должно быть library_item тогда и только тогда, когда объявление модуля программы является library_item. В library_unit_renaming_declaration имя (старое) name должно обозначать library_item.
END_OF_DOCUMENT_MARKER A parent_unit_name (which can be used within a defining_program_unit_name of a library_item and in the separate clause of a subunit), and each of its prefixes, shall not denote a renaming_declaration. On the other hand, a name that denotes a library_unit_renaming_declaration is allowed in a nonlimited_with_clause and other places where the name of a library unit is allowed.
Если библиотечный пакет является экземпляром обобщённого пакета, то каждый элемент этого библиотечного пакета должен быть либо сам экземпляром, либо переименованием библиотечного элемента.
Элемент обобщённого библиотечного пакета должен быть либо сам обобщённым элементом, либо переименованием какого-либо другого элемента того же обобщённого элемента.
Элемент родительского обобщённого пакета должен быть инстанцирован или переименован только в декларативной области родительского обобщённого элемента.
Для каждого элемента C родительского обобщённого пакета P существует соответствующая декларация C, вложенная непосредственно в каждый экземпляр P. Для целей этого правила, если элемент C имеет элемент D, каждая соответствующая декларация для C имеет соответствующий элемент D. Соответствующая декларация элемента в экземпляре видна только в области видимости with_clause, в котором упомянут (исходный) обобщённый элемент.
Библиотечная подпрограмма не должна переопределять примитивную подпрограмму.
Идентификатор функции, являющейся единицей компиляции, не должен быть operator_symbol.
Статическая семантика
A subprogram_renaming_declaration that is a library_unit_renaming_declaration is a renaming-as-declaration, not a renaming-as-body.
Существует два типа зависимостей между единицами компиляции:
- Семантические зависимости (см. ниже) — это зависимости, необходимые для проверки правил компиляции через границы единиц компиляции; единица компиляции зависит семантически от других единиц компиляции, необходимых для определения её корректности. Правила видимости основаны на семантических зависимостях.
- Зависимости выработки (см. 10.2) определяют порядок выработки library_items.
Элемент библиотеки library_item семантически зависит от своей родительской декларации. Подраздел зависит семантически от своего родительского тела. Тело библиотечного элемента library_unit_body семантически зависит от соответствующей декларации library_unit_declaration, если она есть. Декларация ограниченного представления библиотечного пакета семантически зависит от декларации ограниченного представления своего родителя. Декларация библиотечного пакета семантически зависит от декларации его ограниченного представления. Единица компиляции семантически зависит от каждого library_item, упомянутого в with_clause единицы компиляции. Кроме того, если данная единица компиляции содержит attribute_reference типа, определённого в другой единице компиляции, то данная единица компиляции семантически зависит от другой единицы компиляции. Связь семантической зависимости является транзитивной.
Динамическая семантика
Выполнение декларации ограниченного представления пакета не оказывает никакого влияния.
ПРИМЕЧАНИЕ 1 Простая программа может состоять из одной единицы компиляции. Компиляция может не содержать единиц компиляции; например, её текст может состоять из pragmas.
ПРИМЕЧАНИЕ 2 Оператор библиотечной функции не может быть operator_symbol, но небиблиотечная renaming_declaration может переименовать библиотечную функцию как оператор. В пределах раздела две библиотечные подпрограммы должны иметь разные имена и, следовательно, не могут перегружать друг друга. Однако renaming_declaration разрешают определять перегруженные имена для таких подпрограмм, а локально объявленная подпрограмма может перегружать библиотечную подпрограмму. Расширенное имя Standard.L может использоваться для обозначения корневого библиотечного элемента L (если декларация Standard скрыта), так как декларации корневых библиотечных элементов находятся непосредственно в декларативной области пакета Standard.
Примеры
Примеры библиотечных элементов:
package Rational_Numbers.IO is -- общедоступный элемент Rational_Numbers, см. 7.1
procedure Put(R : in Rational);
procedure Get(R : out Rational);
end Rational_Numbers.IO;
procedure Put(R : in Rational);
procedure Get(R : out Rational);
end Rational_Numbers.IO;
private procedure Rational_Numbers.Reduce(R : in out Rational);
-- закрытый элемент Rational_Numbers
-- закрытый элемент Rational_Numbers
with Rational_Numbers.Reduce; -- обращение к закрытому элементу
package body Rational_Numbers is
...
end Rational_Numbers;
package body Rational_Numbers is
...
end Rational_Numbers;
with Rational_Numbers.IO; use Rational_Numbers;
with Ada.Text_io; -- см. A.10
procedure Main is -- корневая процедура библиотеки
R : Rational;
begin
R := 5/3; -- создание рационального числа, см. 7.1
Ada.Text_IO.Put("The answer is: ");
IO.Put(R);
Ada.Text_IO.New_Line;
end Main;
with Ada.Text_io; -- см. A.10
procedure Main is -- корневая процедура библиотеки
R : Rational;
begin
R := 5/3; -- создание рационального числа, см. 7.1
Ada.Text_IO.Put("The answer is: ");
IO.Put(R);
Ada.Text_IO.New_Line;
end Main;
with Rational_Numbers.IO;
package Rational_IO renames Rational_Numbers.IO;
-- декларация переименования библиотечного элемента
package Rational_IO renames Rational_Numbers.IO;
-- декларация переименования библиотечного элемента
Каждый из перечисленных выше library_items может быть подан на компиляцию отдельно.