Глава 10. СТРУКТУРА ПРОГРАММЫ И РЕЗУЛЬТАТ КОМПИЛЯЦИИ

Содержание

10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ
10.2. СУБМОДУЛИ КОМПИЛИРУЕМЫХ МОДУЛЕЙ
10.3. ПОРЯДОК КОМПИЛЯЦИИ
10.4. ПРОГРАММНАЯ БИБЛИОТЕКА
10.5. ПРЕДВЫПОЛНЕНИЕ БИБЛИОТЕЧНЫХ МОДУЛЕЙ
10.6. ОПТИМИЗАЦИЯ ПРОГРАММЫ

В этой главе описываются общая структура программы и средства раздельной компиляции. Программа представляет собой набор из одного или нескольких компилируемых модулей, подаваемых на вход компилятора в виде одной или нескольких компиляций. Каждый компилируемый модуль определяет раздельную компиляцию некоторой конструкции. Ею может быть описание или тело подпрограммы, описание или тело пакета, описание или тело настраиваемого модуля или же конкретизация настройки. Кроме того, компилируемый модуль может быть субмодулем, т.е. телом подпрограммы, пакета, задачи, или настраиваемым модулем, описанным внутри другого компилируемого модуля.

Ссылки: задача 9, компилируемый модуль 10.1, компиляция 10.1, конкретизация настройки 12.3, настраиваемое тело 12.2, описание настройки 12.1, описание пакета 7.1, описание подпрограммы 6.1, субмодуль 10.2, тело задачи 9.1, тело пакета 7.1, тело подпрограммы 6.3.

10.1. КОМПИЛИРУЕМЫЕ МОДУЛИ. БИБЛИОТЕЧНЫЕ МОДУЛИ

Текст программы может подаваться на вход компилятора в виде одной или нескольких компиляций. Каждая компиляция представляет собой последовательность компилируемых модулей.

компиляция ::= (компилируемый-модуль)компилируемый-модуль ::=     спецификатор-контекста библиотечный-модуль  | спецификатор-контекста вторичный-модульбиблиотечный-модуль ::= описание-подпрограммы  | описание-пакета | описание-настройки   | конкретизация-настройки | тело-подпрограммывторичный-модуль ::=    тело-библиотечного-модуля | субмодультело-библиотечного-модуля ::=     тело-подпрограммы | тело-пакета

Говорят, что компилируемые модули программы принадлежат программной библиотеке. Компирируемый модуль определяет библиотечный модуль или вторичный модуль. Вторичный модуль — это раздельно компилируемое соответствующее тело библиотечного модуля или субмодуль другого компилируемого модуля. Обозначением раздельно компилируемой подпрограммы (библиотечного модуля или субмодуля) должен быть идентификатор. В программной библиотеке простые имена всех библиотечных модулей должны быть различными идентификаторами.

Результат компилирования библиотечного модуля состоит в том, чтобы определить (или переопределить) его как модуль программной библиотеки. По правилам видимости каждый библиотечный модуль рассматривается как описание, приведенное непосредственно внутри пакета STANDARD.

Результат компилирования вторичного модуля состоит в том, чтобы определить тело библиотечного модуля или в случае субмодуля соответствующее тело программного модуля, описанного внутри другого компилируемого модуля.

Тело подпрограммы в качестве компилируемого модуля рассматривается как вторичный модуль в том случае, если программная библиотека уже содержит библиотечный модуль, который является подпрограммой с тем же именем. В противном случае оно рассматривается одновременно и как библиотечный модуль, и как соответствующее этому библиотечному модулю тело (т.е. как вторичный модуль).

Компилируемые модули одной компиляции транслируются в заданном порядке. Относящаяся ко всей компиляции прагма должна помещаться перед первым компилируемым модулем компиляции.

Подпрограмма, являющаяся библиотечным модулем, может использоваться в качестве главной программы в традиционном смысле. Главная программа выполняется так, как будто она вызвана некоторой внешней задачей, средства инициализации этого выполнения языком не предписаны. Реализация может предъявить определенные требования к параметрам и результату (если он есть) главной программы (эти требования должны быть приведены в приложении F). Каждая реализация должна разрешать задание в качестве главной программы процедуры без параметров. Любая главная программа должна быть подпрограммой — библиотечным модулем.

Примечание. Простая программа может состоять из одного компилируемого модуля. Компиляция может не содержать ни одного компилируемого модуля, например ее текст может состоять из одних прагм.

Обозначение библиотечной функции не может быть знаком операции, но для переименования библиотечной функции в операцию допускается использование описания переименования. Две библиотечные подпрограммы должны иметь различные простые имена и потому не могут быть совмещены друг с другом. Однако описания переименования могут определить совмещенные имена для таких подпрограмм; кроме того, с библиотечной подпрограммой можно совмещать локально описанную подпрограмму. Так как библиотечные модули рассматриваются как описания, приведенные непосредственно в пакете STANDARD, то для библиотечного модуля L может быть использовано расширенное имя STANDARD.L (если только имя STANDARD не скрыто).

Ссылки: библиотечный модуль 10.5, видимость 8.3, должно 1.6, допустимо 1.6, задача 9, знак операции 6.1, идентификатор 2.3, имя 4.3, конкретизация настройки 12.3, локальное описание 8.1, находится непосредственно в 8.1, окружение 10.4, операция 4.5, описание 3.1, описание настройки 12.1, описание пакета 7.1, описание переименования 8.5, описание подпрограммы 6.1, пакет STANDARD 8.6, параметр подпрограммы 6.2, подпрограмма 6, прагма 2.8, программный модуль 6, простое имя 4.1, процедура 6.1, скрытие 8, совмещение 6.6, 8.7, соответствующее тело 10.1.1, спецификатор контекста 10.1.1, тело пакета 7.1, тело подпрограммы 6.3, указывать 6.1.

10.1.1. СПЕЦИФИКАТОРЫ КОНТЕКСТА. СПЕЦИФИКАТОРЫ СОВМЕСТНОСТИ

Для указания библиотечных модулей, имена которых используются в' компилируемом модуле, служит спецификатор контекста.

спецификатор-контекста ::=   {спецификатор-совместности {спецификатор-использования}}спецификатор-совместности ::=   with простое-имя-модуля {, простое-имя-модуля};

Имена в спецификаторе контекста должны быть простыми именами библиотечных модулей. В спецификаторе совместности допустимы простые имена любых библиотечных модулей. В спецификаторе использования допустимы простые имена только тех библиотечных пакетов, которые указаны в предшествующих спецификаторах совместности данного спецификатора контекста. В спецификаторе контекста недопустимы простые имена, введенные описанием переименования.

Спецификаторы совместности и использования в спецификаторе контекста библиотечного модуля применяются к этому библиотечному модулю и ко вторичному модулю, который определяет соответствующее тело (независимо от того, повторен ли такой спецификатор для вторичного модуля или нет). Аналогично для компилируемого модуля спецификаторы совместности и использования в спецификаторе контекста применяются к этому модулю и к его субмодулям (если они есть).

Библиотечный модуль, упомянутый в спецификаторе совместности, примененном к компилируемому модулю, видим непосредственно внутри этого компилируемого модуля, исключая случаи его скрытия; этот библиотечный модуль видим как описанный непосредственно в пакете STANDARD (см. 8.6).

Спецификаторы совместности задают зависимости между компилируемыми модулями, т.е. компилируемый модуль зависит от других библиотечных модулей, упомянутых в спецификаторе контекста. Зависимости между модулями учитываются при определении допустимогопорядка компиляции (и перекомпиляции) компилируемых модулей (см. разд. 10.3), а также при определении допустимого порядка предвыполнения компилируемых модулей (см. разд. 10.5).

Примечание. Внутри компилируемого модуля видимы библиотечные модули, упомянутые в спецификаторе совместности (исключая случаи их скрытия), следовательно, они могут использоваться как соответствующие программные модули. Так, в компилируемом модуле имя библиотечного пакета может быть дано в спецификаторе использования и служит для формирования расширенных имен; библиотечные подпрограммы можно вызывать; можно описать конкретизации библиотечного настраиваемого модуля.

Правила для спецификаторов совместности дают одинаковый результат как при упоминании имени библиотечного модуля один или несколько раз, в различных спецификаторах совместности, так и внутри заданного спецификатора совместности.

Пример 1. Главная, программа.

Ниже приведен пример главной программы, состоящей из одного компилируемого модуля — процедуры печати вещественных корней квадратного уравнения. Предполагается, что в программной библиотеке уже содержится предопределенный пакет TEXT-10 и заданный пользователем пакет REAL-OPERATIONS (содержащий определения типа REAL и пакетов REAL-10 и REAL-FUNCTIONS). Такие пакеты могут быть использованы и другими главными программами.

with TEXT_IO, REAL_OPERATIONS; use REAL_OPERATIONS;procedure QUADRATIC_EQUATION is   А, В, С, D : REAL:   use REAL_IO,  -- обеспечивает прямую видимость GET и PUT для REAL       TEXT_IO,        -— обеспечивает прямую видимость NEW-LINE и PUT для строк       REAL_FUNCTIONS; -— обеспечивает прямую видимость функции SORT begin   GET(A); GET(B); GET(C);   D := B**2 - 4.0*A*C;   if D < 0.0 then      PUT("lmaginary Roots.");   else      PUT("Real Roots : XI = ");      PUT((-B - SQRT(D))/(2.0*A)); PUT(" X2 = ");      PUT((-B + SQRT(D))/(2.0*A));   end if;   NEW_LINE;end QUADRATIC_EQUATION;

Примечание к примеру. В спецификаторах совместности компилируемого модуля надо упоминать имена только тех библиотечных подпрограмм или пакетов, видимость которых действительно необходима внутри модуля. Нет необходимости (и не следует) упоминать имена других библиотечных модулей, используемых внутри модулей, перечисленных в этих спецификаторах совместности, кроме тех, которые используются непосредственно в данном компилируемом модуле. Например, в теле пакета REAL-OPERATIONS могут потребоваться некоторые элементарные операции, определенные в других пакетах. Но эти пакеты не надо упоминать в спецификаторе совместности процедуры QUADRATIC-EQUATION, так как в ее теле элементарные операции не вызываются непосредственно.

Ссылки: библиотечный модуль 10.1, видимость 8.3, вторичный модуль 10.1, главная программа 10.1, должно 1.6, допустимо 1.6, имя 4.1, компилируемый модуль 10.1, настраиваемое тело 12.2, настраиваемый модуль 12.1, непосредственная видимость 8.3, описание пакета 7.1, описание подпрограммы 6.1, пакет 7, пакет STANDARD 9.6, пред выполнение 3.9, программный модуль 6, простое имя 4.1, процедура 6.1, скрытие 8.3, спецификатор использования 8.4, субмодуль 10.2, тело пакета 7.1, тело подпрограммы 6.3, тип 3.3, экземпляр 12.3.

10.1.2. ПРИМЕРЫ КОМПИЛИРУЕМЫХ МОДУЛЕЙ

Компилируемый модуль может быть расчленен на несколько компилируемых модулей. Например, рассмотрим следующую программу:

procedure PROCESSOR is   SMALL : constant := 20;   TOTAL : INTEGER := 0;   package STOCK is      LIMIT : constant := 1000;      TABLE : array (1 .. LIMIT) of INTEGER;      procedure RESTART;   end STOCK;   package body STOCK is      procedure RESTART is      begin         for N in 1 .. LIMIT loop             TABLE(N) := N;         end loop;      end;   begin      RESTART;   end STOCK;   procedure UPDATE(X : INTEGER) is      use STOCK;   begin      ...      TABLE(X) := TABLE(X) + SMALL;   end UPDATE;begin   STOCK.RESTART;   -- переинициализация TABLE end PROCESSOR;

Приведенные ниже три компилируемых модуля определяют программу с результатом, эквивалентным результату предыдущего примера (пунктирные линии между модулями напоминают, что они не обязаны составлять единый текст).

Пример 2. Несколько компилируемых модулей.

package STOCK is   LIMIT : constant := 1000;   TABLE : array (1 .. LIMIT) of INTEGER;   procedure RESTART;end STOCK;package body STOCK is   procedure RESTART is   begin      for N in 1 .. LIMIT loop          TABLE(N) := N;      end loop;   end;begin   RESTART;end STOCK;with STOCK;procedure PROCESSOR is   SMALL : constant   := 20;   TOTAL : INTEGER := 0;   procedure UPDATEIX : INTEGER) is      use STOCK;   begin      TABLE(X) := TABLE(X) + SMALL;   end UPDATE;begin   ...   STOCK.RESTABT; —-  nepeинициализация TABLE   ...end PROCESSOR

Заметим, что в последней версии примера в пакете STOCK невидимы внешние идентификаторы, отличные от предопределенных (в пакете STANDARD). В частности, в нем не используются идентификаторы SMALL и TOTAL, описанные в процедуре PROCESSOR; в противном случае пакет STOCK нельзя выделить из процедуры PROCESSOR, как это сделано выше. С другой стороны, процедура PROCESSOR зависит от пакета STOCK и упоминает его в спецификаторе совместности. Поэтому пакет STOCK можно использовать в расширенном имени и спецификаторе использования.

Эти три компилируемых модуля могут быть организованы как одна или несколько компиляций. Например, возможно объединение в одной компиляции спецификации и тела пакета в указанном порядке.

Ссылки: видимость 8.3, идентификатор 2.3, компилируемый модуль 10.1, описание 3.1, пакет 7, пакет STANDARD 8.6, программа 10, спецификатор использования 8.4, спецификатор совместности 10.1.1, спецификация пакета 7.1, тело пакета 7.1.