1. Именованный тип эквивалентен сам себе.

2. Если тип T=tid(I,B) имеет описание declared(I,B,T1), где T1 – именованный тип, то типы T и T1 эквивалентны.

Это очень ограничительное определение. Даже в Паскале допустимо присваивание

U:=V,

если переменные U и V описаны как

var U,V: array[1..10]of real,

хотя имеют неименованный тип "массив". Но в том же Паскале этот оператор недопустим из-за неэквивалентности типов переменных, если они описаны как

var U: array[1..10]of real;

var V: array[1..10]of real;

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

В соответствии со сказанным следует внести изменения в правила DC-грамматики для нетерминала type, определяющие атрибут типа. В них включается теперь порождение и описание псевдонимов типа. Для генерации новых "имен" можно использовать самые разные методы; мы здесь воспользуемся предикатом recorda, генерирующем в качестве псевдонима уникальную ссылку на пустой терм, записываемый по ключу alias. описание этого псевдонима типа включается в виде предиката declared.

type(B,tid(A,B)) -->

[array,`[,n(M),`:,n(N),`],of],type(B,T),

{recorda(alias,_,A),

assert(declared(A,B,type(arr(M,N,T)))}.

type(B,tid(A,B)) -->

[record],field(B,F),fields(B,LF),

{correct(F,LF),

recorda(alias,_,A),

assert(declared(A,B,type(rec([F|LF])))},

[end].

type(B,tid(A,B)) -->

[`^,id(I)],

{(type_id2(I,B,B1,type(_));

assert(declared(I,B,type(referred))),

B1=B),

recorda(alias,_,A),

assert(declared(A,B,type(ref(I,B1)))}.

Предикат consist в этом случае определяется следующим образом:

consist(T1,T2):T1=int,T2=real ; % приводимость

equiv(T1,T2) ; % эквивалентность

error("Несовместимые типы").

equiv(T,T).

equiv(tid(I,B),tid(I1,B1)):declared(I,B,type(tid(I1,B1)));

declared(I1,B1,type(tid(I,B))).

Именная эквивалентность сравнительно просто реализуется. Но это – отношение (рефлексивное и симметричное) не транзитивно, и поэтому не является эквивалентностью ни в математическом, ни в привычном, обыденном смысле. Понятие псевдонима типа обычно не даётся программистам, Поэтому начинающие программисты на Паскале часто делают ошибки, вроде указанных в примере. Мотивацией для введения именной эквивалентности в 1970-е годы послужило желание избежать ошибок программирования, вроде присваивания "яблокам" "крабов", когда и те, и другие описаны как целые. С развитием объектно-ориентированного программирования подобные ухищрения стали излишними, а именная эквивалентность осталась в некоторых языках как анахронизм.

Структурно-именная эквивалентность

Этот тип эквивалентности самый простой: эквивалентными считаются типы, имеющие одинаковый базовый тип. Предикат consist в этом случае определяется следующим образом:

consist(T1,T2):base_type(T1,BT1),base_type(T2,BT2),

(BT1=int,BT2=real ; % приводимость

BT1=BT2 ; % эквивалентность

error("Несовместимые типы")).

При этом нет необходимости вводить псевдонимы типа, как в случае именной эквивалентности. Вместо предиката acc_type при анализе доступа можно применять предикат base_type.

Отношение структурно-именной эквивалентности рефлексивно, симметрично и транзитивно. По вложению оно лежит строго между структурной и именной эквивалентностями. Им легко пользоваться на практике.

Примеры

1.

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

Program Code_pf_Char;

{Программа читает символ с клавиатуры и выводит на экран

этот символ и соответствующий ему внутренний код}

var

ch: Char; {В эту переменную читается символ}

begin

Write('Введите любой символ: ');

ReadLn(ch); {Читаем один символ}

WriteLn(ch, ' = ',ord(ch)); {Преобразуем его к целому и выводим на экран}

END.

Обращаем внимание: при вызове

WriteLntch,' = ',ord(ch));

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

2.

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

Непроизносимые гласные:

Сочетания "вств" и "стн" транскрибируются как [ств] и [сн] соответственно, т. е.:

1) /вств/ -> [ств]

2) /стн/ -> [лнц]

Реализация двух данных правил на языке Паскаль:

program transcription;

var

Word: String;

I, J, K: Integer;

begin

Write('Введите слово: '); ReadLn(Word);

K := Pos('вств', word);

while (K 0) do

begin

delete(Word, K, 1);

K := Pos('вств', Word);

end;

K := Pos('стн', Word);

while (K 0) do

begin

delete(Word, K+1, 1);

K := Pos('стн', Word);

end;

WriteLn('Транскрипция: ', Word);

end.

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


Информация о работе «Совместимость и преобразование типов данных»
Раздел: Иностранный язык
Количество знаков с пробелами: 21088
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
362757
48
34

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

Скачать
37739
31
0

... Эти три проблемы осложняют использование BCB dll из приложений, созданных на VC, но все-таки это возможно. Ниже описаны три способа создания dll совместимой с VC и дальнейшего успешного использования этой dll. Алгоритмы создания VC-совместимой dll и ее использование Два из описанных в этом разделе алгоритмов применяют неявное связывание с dll, один – явную загрузку dll. Опишем сначала самый ...

Скачать
29034
4
1

... фактически игнорирует это указание: “упаковка” данных в Object Pascal осуществляется автоматачески везде, где это возможно.   1.2.1 Массивы Массивы в Object Pascal во многом схожи с аналогичными типами данных в других языках программирования. Отличительная особенность массивов заключается в том, что все их компоненты суть данные одного типа (возможно, структурированного). Эти компоненты можно ...

Скачать
194681
23
7

... поставленной задачи показала правильность выбранного подхода. Тем не менее, работа требует дальнейше доработаки для организации постоянного доступа читателей к библиографическим ресурсам библиотекам города через Интернет. Литература 1.          Глушаков С.В., Ломотьков Д.В. Базы данных: Учебный курс. – К.: Абрис, 2000. -504с. 2.          Джейсон Мейнджер. Java: основы программирования :Пер ...

0 комментариев


Наверх