Курсовая работа: Совместимость и преобразование типов данных

5. Если нетерминалу t соответствует базовый тип ref(tid(I,B)), а типу tid(I,B) уже сопоставлен нетерминал t1, то вводится правило t -> ^ t1.

Нетерминалы этой грамматики эквивалентны, если и только если соответствующие типы структурно эквивалентны.

Остаётся преобразовать эту грамматику к автоматному виду и применить алгоритм нахождения всех пар эквивалентных состояний.

Отношение структурной эквивалентности действительно является эквивалентностью, т.к. оно рефлексивно, транзитивно и симметрично. Кроме того, два типа структурно эквивалентны тогда и только тогда, когда они допускают одни и те же последовательности операций. Это делает такую эквивалентность простой и понятной программистам. Её основным и весьма существенным недостатком является сложный и громоздкий алгоритм проверки эквивалентности. Насколько известно автору, структурная эквивалентность была принята только в языке Алгол 68.

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

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

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

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

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

Именная эквивалентность

При стандартизации языка Паскаль была принята именная эквивалентность. Согласно её определению эквивалентными могут быть только именованные типы, т.е. типы с атрибутами int, real или tid(_,_):

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),

К-во Просмотров: 308
Бесплатно скачать Курсовая работа: Совместимость и преобразование типов данных