Технология построения многовариантных объектно-ориентированных структур текстов
Вид материала | Диссертация |
СодержаниеКвалификация имен сущностей Поиск сущностей по имени Типы данных ТОМАТа Инструкции языка ТОМАТа Константы языка ТОМАТа Операторы языка ТОМАТа |
- Ландшафт области управления данными: аналитический обзор, 531.27kb.
- Развитие объектно-ориентированных систем управления базами данных, 122.52kb.
- Лекция № Элементы управления в графических и объектно-ориентированных интерфейсах, 307.9kb.
- Сводный научный отчет за 2010 г по совместному проекту «Разработка объектно-ориентированных, 204.3kb.
- Врамках настоящей работы на примере четырех произведений будут рассмотрены некоторые, 228.04kb.
- Программа вступительного экзамена по специальности 05. 13. 18 Математическое моделирование,, 115.33kb.
- Рабочая программа учебной дисциплины (модуля) Объектно-ориентированное программирование, 99.17kb.
- Исследование организационных структур управления, 469.08kb.
- Темы: Введение в язык rsl, 123.68kb.
- Программа дисциплины Объектно-ориентированное программирование Рекомендуется для направления, 591.42kb.
Для лучшего понимания контекстов ссылок по именам, на основе приведенной выше информации построен следующий список сущностей, которые могут ссылаться с помощью языка ТОМАТа на другие именованные сущности. В квадратных скобках указаны контексты появления этих ссылок, в круглых скобках — именованные сущности, на которые может производиться ссылка (указания в круглых скобках за пределами квадратных относятся к каждому элементу в квадратных скобках).
- Действие — текст
[
Класс (поле создаваемого класса),
Узел (поле класса узла),
Поле (поле, являющееся предметом ограничения),
Шаблон (поле создаваемого класса, либо поле класса некоторого неопционального узла),
]
(Константа, Токен)
- Константа — значение (Константа, Токен)
- Поле — значение по умолчанию (Константа, Токен)
Примечание: под создаваемым классом в контексте действий понимается класс, объект которого только что создан, и для него проверяются ограничения и выполняются присваивания.
В приведенном списке отражено ограничение языка ТОМАТа, запрещающее в шаблоне ссылаться на поле опционального узла.
Это ограничение не является фундаментальным свойством технологии "ТОМАТ". В процессе разработки технологии было предложено несколько различных пониманий, как обрабатывать такие ссылки при отсутствии опционального узла в конкретном покрытии. Например, игнорировать целиком действия, содержащие такие ссылки. Или исключать из вычислительного процесса подвыражения с такими ссылками (например, минимальное булевское подвыражение заменять на True). Однако, было отмечено, что такие подходы сложны для понимания и требуют особой внимательности при конструировании шаблонов, так как провоцируют появление трудно обнаружимых ошибок. Поэтому было решено отказаться от возможности ссылаться в действиях шаблона на поля опциональных узлов, а все необходимые ограничения на такие узлы описывать в самом узле. При этом не происходит сужения функциональных возможностей.
Вообще говоря, точное определение синтаксиса имен — задача конкретной реализации. Существенной рекомендацией, следование которой выводит за рамки традиций большинства языков программирования, является допуск в имени символов, представляющих буквы не латинского алфавита (в случае, если в реализации принята кодировка символов типа Unicode, поддерживающая многоязычность). Можно вообще приравнять к буквам любые символы, не входящие в набор символов кодировки ASCII, как и было сделано в базовой реализации. Кроме того, рекомендуется различать регистр символов, так как это упрощает реализацию и дает большие возможности по именованию.
Для наглядности приведем список сущностей ТОМАТа, имеющих имена:
- Банк
- Домен
- Константа
- Класс
- Шаблон
- Токен
- Поле
- Узел
В большинстве языков программирования имя (идентификатор, выбранный пользователем) не может совпадать с зарезервированными словами языка, а они наверняка будут присутствовать в любой реализации языка ТОМАТа. Для обеспечения совместимости по языку ТОМАТа между различными реализациями (например, путем построения программ-переводчиков описаний системы классов и шаблонов между языками разных реализаций) рекомендуется следующий прием. Можно использовать некий символ (в базовой реализации был выбран "%"), появление которого в начале имени не меняет смысл имени, но гарантирует интерпретацию идентификатора как имени, а не как зарезервированного слова.
Каждое имя сущности ТОМАТа принадлежит некоторому пространству имен, при этом считается, что сущность, обозначенная данным именем, относится к соответствующему пространству имен. Внутри одного пространства имен все имена уникальны.
Все локальные сущности образуют собственные пространства имен для вложенных в них сущностей. Также в каждом банке существуют следующие собственные пространства имен:
- Домены
- Константы и токены (всех доменов банка)
Константы и токены были намеренно помещены в одно пространство имен. Дело в том, что компилятор выражений должен по идентификатору однозначно определить его тип, поэтому среди токенов всех доменов банка не должно быть совпадающих. Константы же попали в то же пространство имен, потому что иначе пришлось бы отдавать приоритет либо константам, либо токенам, но в любом случае добавление в банк новой константы или токена с именем, совпадающим соответственно с неким токеном или константой, могло бы изменить смысл уже написанных выражений, причем, возможно, не нарушая их корректности, таким образом, "тихо" меняя работу системы классов.
- Классы
- Шаблоны
В языке ТОМАТа действует правило обязательного описания сущностей перед использованием (аналогично языку Паскаль). Таким образом, можно ссылаться по имени только на сущность ТОМАТа, описание которой помещено по тексту банка выше места ссылки (либо в одном из используемых банков). Ссылки вперед не допускаются.
Это правило является следствием принятого решения об однопроходности компилятора. Было замечено, что в банке всегда можно расположить сущности в нужном порядке, так как шаблоны описываются отдельно от классов. В первоначальной версии ТОМАТа шаблоны помещались в класс подобно конструкторам в языках программирования общего назначения. Но в этом случае возникала проблема определения двух классов, каждый из которых имеет шаблон с узлом, класс которого является вторым из этих двух классов (взаимно-рекурсивные шаблоны). В предлагаемом варианте языка ТОМАТа такой проблемы нет, так как шаблоны, хотя логически и являются частью класса, описываются после всех классов банка.
- ^ Квалификация имен сущностей
Имена, появляющиеся в различных контекстах, являются ссылками на сущности ТОМАТа. Для уточнения, в каком пространстве имен следует искать сущность, в языке ТОМАТа могут использоваться специальные префиксы к имени, называемые квалификаторами. Квалификаторы по назначению делятся на несколько видов и различаются по символам, завершающим квалификатор, которые называются символами вида квалификатора.
Строго говоря, понятие квалификатора банка принадлежит не только языку ТОМАТа — любые ссылки по именам сущностей, например, имя класса в списке базовых классов, могут быть квалифицированы именем банка. Разумеется, реализациям языка рекомендуется выбирать один и тот же синтаксис для квалификаторов банка в языке ТОМАТа (языке действий), и в таких ссылках, так как смысл обоих видов квалификаторов одинаковый.
Каждое имя глобальной сущности в любом контексте (в том числе в составе другого квалификатора) может быть квалифицировано квалификатором банка (если имя банка опущено, то подразумевается имя текущего банка). Именами, к которым можно применять квалификатор банка, являются имена следующих сущностей ТОМАТа:
- Класс
- Домен
- Константа
В случае наличия квалификатора банка поиск сущности будет производиться только в указанном банке. Это должен быть один из банков, указанных в числе используемых текущим банком, либо пустой квалификатор банка, обсуждавшийся выше.
Каждое имя поля может предваряться квалификатором класса (в базовой реализации символом квалификатора класса является двоеточие). Если указан квалификатор класса, то это означает, что поиск поля следует начать с базового класса с указанным именем. Указание имени класса, не являющегося (возможно, непрямым) базовым классом для класса из контекста (и не совпадающего с именем самого класса из контекста), является ошибкой.
Такая квалификация позволяет решить проблему совпадения имен полей к базовом классе и классе-наследнике. Альтернативой было бы сокрытие унаследованных полей нововведенными одноименными полями (что плохо, так как ограничивает разработчиков классов-наследников в выборе имен), либо запрещение повторного использования имен полей (что еще сильнее ограничивает авторов систем классов и шаблонов).
Необходимо отметить, что квалификатор банка не может применяться к имени поля, и потому не влияет на поиск полей в базовых классах, находящихся в других банках.
В контексте, где возможно обращение как к полям создаваемого класса, так и к полям класса некоторого узла, имя поля можно квалифицировать квалификатором узла (в базовой реализации предлагается символ точки). Наличие этого квалификатора говорит о том, что имеется в виду имя поля вложенного объекта, соответствующего узлу, а не имя поля создаваемого объекта.
- ^ Поиск сущностей по имени
Для того, чтобы найти сущность по имени, с учетом возможных квалификаторов, компилятору рекомендуется руководствоваться изложенными в этом разделе правилами.
Алгоритм поиска глобальных сущностей:
- При поиске имен глобальных сущностей при наличии квалификатора банка поиск производится только в указанном банке (только в текущем, если в квалификаторе опущено имя банка).
- Поиск глобальной сущности при опущенном квалификаторе банка производится следующим образом. Просматривается сначала текущий банк. Если сущность не обнаружена, то происходит поиск в каждом банке, который используется текущим, причем банки просматриваются в том порядке, в котором они указаны в списке используемых банков, и сразу же после обнаружения сущности поиск успешно завершается.
Этот алгоритм используется во всех случаях, когда на глобальную сущность производится ссылка по имени не в тексте выражения, в частности, для поиска класса по имени, указанному в квалификаторе класса. Поиск сущностей по именам, встречающимся в выражениях, производится по следующим правилам:
- Если имя встретилось без квалификатора узла и без квалификатора класса, то при наличии квалификатора банка в указанном банке ищется токен либо константа с заданным именем, а при отсутствии квалификатора банка используется модифицированный алгоритм поиска глобальных сущностей (к нему добавляется промежуточный шаг). Вначале компилятор пытается согласно алгоритму в текущем банке найти токен либо константу с нужным именем. Но если такая сущность не находится, и по контексту выражения возможна ссылка на поле, то перед поиском в используемых банках производится поиск поля в создаваемом классе (либо в классе узла, если выражение находится в узле), причем рассматриваются также все поля базовых классов независимо от банка, в котором они определены. Если и этот поиск не завершится успешно, то производится поиск токена либо константы в используемых банках в продолжение работы алгоритма поиска глобальных сущностей.
- Если же имеется квалификатор узла либо квалификатор класса (либо оба), то производится поиск соответствующего поля с учетом квалификаторов (распределение классов по банкам не влияет на этот поиск). Квалификатор банка, если он имеется, относится к имени класса в квалификаторе класса. Поле ищется в классе указанного узла при наличии квалификатора узла (квалификаторы узла не должны появляться в выражениях, не входящих в шаблон), иначе поле ищется в создаваемом классе (либо в классе узла, если выражение находится в узле), причем рассматриваются также все поля базовых классов независимо от банка, в котором они определены.
- ^ Типы данных ТОМАТа
В технологии "ТОМАТ" рассматривается несколько типов данных, которые используются для хранения информации в объектах. Следует отметить, что все типы в ТОМАТе делятся на два класса: скалярные и множественные. При этом в зависимости от операторов, значения множественных типов могут рассматриваться либо как множества, аналогично языку Паскаль, либо как недоопределенные значения соответствующих скалярных типов.
Скалярные типы могут быть следующими (в скобках приводятся их английские названия, использующиеся в базовой реализации):
- Целый (Integer)
- Логический (Boolean)
- Строковый (String)
- Перечислимый (Domain)
Значением целого типа может являться целое число из некоторого диапазона. Рекомендуется, чтобы реализация технологии выделяла не менее 31 бита для целых чисел.
31 бит был выбран для того, чтобы оставить реализации возможность использовать один из битов значения как флаг множественного типа, при этом остальные биты могут представлять указатель на список отрезков (в большинстве реализаций 31 бита для представления указателя может быть достаточно из-за обязательного требования как минимум четности адреса в большинстве архитектур). Возможны и другие подходы к реализации множеств целых типов.
Значение логического типа — это "истина" либо "ложь".
Значением строкового типа является строка символов (допускаются все символы, поддерживаемые реализацией).
Значением перечислимого типа является один из токенов этого домена, количество токенов в домене может быть ограничено реализацией, но рекомендуется допускать хотя бы 32.
Значения множественного типа должны представляться как множества или списки значений соответствующего типа (в последнем случае порядок хранения значений не должен влиять на семантику). Для перечислимого типа вообще не обязательно вводить отдельное представление для скалярного значения — оно всегда может быть эффективно обработано как множество из одного элемента.
Реализация множества целых чисел может быть следующей. Целые воспринимаются как округленные действительные числа, а множество целых хранится в виде списка отрезков (пары "начало-конец"). В этом случае арифметические операции над недоопределенными целыми рассматриваются, как если бы они проводились над действительными числами, а границы отрезков результатов округлялись. Обязательно следует предусмотреть реализацию полного множества в виде особого значения. Считается, что такое множество представляет всю числовую ось — полностью неопределенной значение.
Множество строк рекомендуется реализовывать в виде списка принадлежащих множеству значений. При этом для множества строк реализацией обязательно должна быть предусмотрена возможность представления полного множества строк (полная неопределенность).
Тип константы определяется автоматически при вычислении ее значения. Он может быть как скалярным, так и множественным. Указание типа в описании константы является избыточным.
Вообще, пользователь технологии ТОМАТ может абстрагироваться от наличия скалярных типов, считая все значения недоопределенными. Скалярные типы были введены для обеспечения возможности эффективной реализации вычислений, таким образом, их упоминание в руководстве пользователя для разработчиков системы классов и шаблонов вообще может быть излишним.
- ^ Инструкции языка ТОМАТа
Действия, которые встречаются в различных сущностях ТОМАТа, содержат инструкции языка ТОМАТа. На данном этапе развития базовой реализации предлагаются пять инструкций: пустая, составная, условная, присваивания и проверки ограничения. В перспективе механизм инструкций может развиться в некий алгоритмический язык с локальными переменными, циклами и т.п. Тогда действия могут представлять программы на алгоритмически полном языке.
Следует отметить, что не все виды инструкций допускаются в действиях в каждом контексте. Принято ограничение, не разрешающее появляться присваиваниям нигде, кроме как в действиях для шаблона.
Разумеется, тип выражения должен совпадать с типом поля. В левой части присваивания может находиться только ссылка на поле, разрешенная для контекста действия. Таким образом, на левую и правую часть присваивания накладываются одинаковые ограничения по возможности ссылаться на поля, в соответствии с контекстом появления действия.
Выражение в инструкции проверки ограничения должно иметь логический тип. Считается, что условие выполнено, если в множество, являющееся результатом выражения, входит True.
В реализации технологии "ТОМАТ" рекомендуется делать оптимизацию вычисления ограничений, основанную на том, что достаточно убедиться, что "истина" попадает в множество-результат. Предлагается алгоритм оптимизации, суть которого сводится к замене выражения (обозначим его E) на выражение "True in (E)". Далее можно рассмотреть самый верхний оператор в дереве операторов выражения и подставить вместо него оптимизированную версию. Рассмотрим это на примере, когда верхним оператором является "or". Выражение "True in (A or B)" можно заменить на "(True in A) or' (True in B)", где "or'" — классический оператор "ИЛИ", работающий только со скалярными значениями, и не вычисляющий второй аргумент, если значение первого полностью определяет результат. Выражения "True in A" и "True in B" оптимизируются аналогично по рекурсии.
Как отмечалось выше, семантика работы с множественными узлами достаточно сложна. Она описана в разделе, посвященном исполнителю, поскольку технология "ТОМАТ" сконструирована таким образом, чтобы ни компилятор выражений, ни вычислитель выражений не зависели от этой семантики — компилятор подставляет вместо ссылок на имена полей их индексы, а вычислитель принимает на вход от исполнителя ссылку на данные полей (на что она будет ссылаться, определяется исполнителем).
- ^ Константы языка ТОМАТа
В выражениях и некоторых других конструкциях языка ТОМАТа могут использоваться константы (явно указанные значения), называемые константами языка ТОМАТа (в отличие от именованных констант, описанных в банке, являющихся сущностями ТОМАТа).
Для перечислимого типа константой является просто имя соответствующего токена, возможно, с квалификатором банка.
Константа целого типа описывается десятичным либо шестнадцатеричным числом (реализация может предлагать и другие способы записи целых). В языке желательно наличие встроенной константы для максимального представимого целого (в базовой реализации предлагается обозначение "MaxInt").
Константа логического типа описывается ключевым словом, например "False" и "True", как предложено в базовой реализации.
Строковая константа задается строкой символов в кавычках (или апострофах, как в базовой реализации). Реализация должна обеспечивать возможность формирования строковой константы из произвольного допустимого символа с известным кодом. Полезно ввести правило о том, что подряд идущие строковые константы (возможно, разделенные пробельными символами, к которым приравнены и комментарии) конкатенируются, аналогично языку C [Керниган, Ритчи 2001].
Обязательно предусмотреть возможность указания константы пустого множества заданного типа, а также полного множества — содержащего все возможные элементы (полная неопределенность).
В случаях, когда требуется указать константу множественного типа, отличную от пустого и полного множеств, можно воспользоваться оператором объединения множеств (см. ниже).
- ^ Операторы языка ТОМАТа
Операторы используются в выражениях (в том числе константных) для совершения операций над данными. С точки зрения грамматики, каждый оператор принимает аргументы любых типов, однако при компиляции накладываются дополнительные ограничения. Таким образом у одного оператора может быть различная семантика (вплоть до запрета использования) применительно к разным типам, но названия операторов, их приоритеты, количество аргументов и т.п. не зависят от типа аргументов.
Все операторы способны принимать аргументы как множественного типа, так и скалярных. При этом скалярные значения всегда интерпретируются как множества из одного элемента.
Операторы можно разделить на два класса. Первый класс операторов (скалярные) содержит операторы, интерпретирующие аргументы как недоопределенные значения, например, операторы сложения, конкатенации и т.п. (эти операторы имеют традиционную семантику для скалярных значений). Фактически, для двух множеств это означает добавление к множеству-результату (изначально пустому) результата операции для каждого с каждым из аргументов. Второй класс операторов (множественные) содержит операторы, подразумевающие интерпретацию аргументов как множеств, например, оператор пересечения, проверки пустоты и т.п.
Тип возвращаемого значения однозначно определяется по аргументам оператора. Типы аргументов должны совпадать (при этом скалярные и соответствующие им множественные типы могут смешиваться) для всех операторов за исключением оператора индексирования строк..
Для эффективной реализации вычисления выражений предполагается, что компилятор выражений вызывает оптимизатор перед генерацией кода для выражения, который вычисляет константные подвыражения (возможно, эксплуатируя коммутативность некоторых операторов), а также подставляет оптимизированные версии операторов при использовании скалярных аргументов. В качестве результирующего кода для выражений рекомендуется ПОЛИЗ.
Далее приводится описание скалярных и множественных операторов с указанием типов аргументов и возвращаемого значения. В этом списке T — любой тип Integer, Boolean, String или перечислимый, E — любой тип Integer, Boolean или перечислимый. Операторы перечисляются в порядке понижения приоритета. Операторы одного приоритета вычисляются слева направо. Обозначения операторов заимствованы из базовой реализации, другие реализации языка ТОМАТа могут вводить свои обозначения и дополнительные операторы.
Перечислим множественные операторы языка ТОМАТа (они имеют больший приоритет, чем скалярные).
- E ".." E: E
Оператор конструирования отрезка. Началом отрезка-результата считается минимальное начало отрезка из первого аргумента, концом - максимальный из концов второго, при этом если начало отрезка-результата получается больше конца, то результатом будет пустое множество.
- T ("