Руководство по Ada 2012
2.8 Предикаты
Предикат — это директива компилятора. Существуют определяемые языком предикаты, которые дают инструкции для оптимизации, управления списком вывода и т. д. Реализация может поддерживать дополнительные (определяемые реализацией) предикаты.
Синтаксис
pragma ::=
pragma идентификатор [(ассоциация_аргумента_предиката {, ассоциация_аргумента_предиката})];
pragma идентификатор [(ассоциация_аргумента_предиката {, ассоциация_аргумента_предиката})];
ассоциация_аргумента_предиката ::=
[аргумент_предиката_идентификатор =>] имя
| [аргумент_предиката_идентификатор =>] выражение
| аргумент_предиката_метка_аспекта => имя
| аргумент_предиката_метка_аспекта => выражение
[аргумент_предиката_идентификатор =>] имя
| [аргумент_предиката_идентификатор =>] выражение
| аргумент_предиката_метка_аспекта => имя
| аргумент_предиката_метка_аспекта => выражение
В предикате, все ассоциации_аргумента_предиката без аргумент_предиката_идентификатор или аргумент_предиката_метка_аспекта должны предшествовать ассоциациям с аргумент_предиката_идентификатор или аргумент_предиката_метка_аспекта.
Предикат разрешается только в следующих местах программы:
После разделителя точки с запятой, но не внутри формальной_части или части_дискриминанта.
В любом месте, где правила синтаксиса разрешают конструкцию, определённую синтаксической категорией, имя которой оканчивается на «объявление», «элемент», «выражение», «оператор» или «вариант», или одной из синтаксических категорий вариант или обработчик_исключений; но не вместо такой конструкции, если конструкция требуется или является частью списка, который должен иметь по крайней мере одну такую конструкцию.
Вместо оператора в последовательность_операторов.
В любом месте, где разрешается единица_компиляции.
Существуют дополнительные правила синтаксиса и ограничения на размещение для определенных предикатов.
Имя предиката — это идентификатор, следующий за ключевым словом pragma. Имя или выражение ассоциации аргумента предиката — это аргумент предиката.
Идентификатор, специфичный для предиката, — это идентификатор или ключевое слово, используемое в аргументе предиката со специальным значением для данного предиката.
Статическая семантика
Если реализация не распознает имя предиката, то оно не оказывает никакого влияния на семантику программы. Внутри такого предиката применяются только правила синтаксиса.
Динамическая семантика
Любой предикат, который появляется на месте исполняемого конструктора, выполняется. Если для конкретного предиката не указано иное, это выполнение состоит из вычисления каждого вычислимого аргумента предиката в произвольном порядке.
Требования к реализации
Реализация должна выдать сообщение об ошибке для нераспознанного имени предиката.
Разрешения реализации
Реализация может предоставлять предикаты, определяемые реализацией; имя определяемого реализацией предиката должно отличаться от имен определяемых языком предикатов.
Реализация может игнорировать нераспознанный предикат, даже если он нарушает некоторые правила синтаксиса, если обнаружение синтаксической ошибки слишком сложно.
Рекомендации по реализации
Обычно определяемые реализацией предикаты не должны оказывать никакого семантического влияния на корректные программы; то есть, если определяемые реализацией предикаты в рабочей программе заменить нераспознанными предикатами, программа всё ещё должна быть корректной и иметь ту же семантику.
Обычно реализация не должна определять предикаты, которые могут сделать некорректную программу корректной, за исключением следующих случаев:
- Предикат, используемый для завершения объявления;
- Предикат, используемый для настройки среды путём добавления, удаления или замены элементов_библиотеки.
Синтаксис
Формы предикатов List, Page и Optimize следующие:
pragma List(идентификатор);
pragma Page;
pragma Optimize(идентификатор);
Другие предикаты определены в этом Международном стандарте и суммированы в Приложении L.
Статическая семантика
Предикат List принимает один из идентификаторов On или Off в качестве единственного аргумента. Этот предикат разрешается в любом месте, где разрешается предикат. Он указывает, что вывод компиляции должен продолжаться или приостанавливаться до тех пор, пока в рамках той же компиляции не будет дан предикат List с противоположным аргументом. Сам предикат всегда выводится, если компилятор генерирует вывод.
Предикат Page разрешается в любом месте, где разрешается предикат. Он указывает, что текст программы, следующий за предикатом, должен начинаться на новой странице (если компилятор в данный момент генерирует вывод).
Предикат Optimize принимает один из идентификаторов Time, Space или Off в качестве единственного аргумента. Этот предикат разрешается в любом месте, где разрешается предикат, и он применяется до конца ближайшей объявляющей области или для предиката в месте единицы компиляции, до конца компиляции. Он даёт рекомендации реализации относительно того, является ли временем или памятью основным критерием оптимизации или следует выключить необязательные оптимизации. Способ реализации этих рекомендаций определяется реализацией.
Примеры
Примеры предикатов:
pragma List(Off); -- выключить генерацию вывода
pragma Optimize(Off); -- выключить необязательные оптимизации
pragma Pure(Rational_Numbers); -- установить категоризацию для пакета
pragma Assert(Exists(File_Name),
Message => "Файл не найден"); -- убедиться, что файл существует
pragma Optimize(Off); -- выключить необязательные оптимизации
pragma Pure(Rational_Numbers); -- установить категоризацию для пакета
pragma Assert(Exists(File_Name),
Message => "Файл не найден"); -- убедиться, что файл существует