Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Выражения



ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ::=

КОНСТАНТА | ПЕРЕМЕННАЯ | АГРЕГАТ | ИМЯ-ПРЕДИКАТА |

ГЕНЕРАТОР-ПРЕДИКАТА | ВЫЗОВ-ФУНКЦИИ | ( ВЫРАЖЕНИЕ ) | ИМЯ-ТИПА |

МОДИФИКАЦИЯ | ЭЛЕМЕНТ-СПИСКА | ОПРЕДЕЛЕНИЕ-МАССИВА |

КОНСТРУКТОР | РАСПОЗНАВАТЕЛЬ | ПОЛЕ-ОБЪЕДИНЕНИЯ

Имя типа может быть аргументом вызова предиката и изображения типа. Определение ЭЛЕМЕНТА-СПИСКА дается в разд. 6.7. Операция ОПРЕДЕЛЕНИЕ-МАССИВА описывается в разд. 6.8.3. Последние три альтернативы в определении ПЕРВИЧНОГО-ВЫРАЖЕНИЯ относятся к объектам типа объединения и описаны в разд. 6.7.

ПЕРЕМЕННАЯ::= ИМЯ-ПЕРЕМЕННОЙ | ЭЛЕМЕНТ-МАССИВА | ПОЛЕ-СТРУКТУРЫ |

ПЕРЕМЕННАЯ-КЛАССА | ВЫРЕЗКА-МАССИВА |

МУЛЬТИПЕРЕМЕННАЯ

ВЫРЕЗКА-МАССИВА определена в разд. 6.8.

ИМЯ-ПЕРЕМЕННОЙ::= ИДЕНТИФИКАТОР [ ]

Переменная вида имя’ используется для именования результата предиката. Переменная имя’ склеивается с переменной имя, являющейся аргументом предиката (см. разд. 6.3.1).

ЭЛЕМЕНТ-МАССИВА::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ [ ИНДЕКСЫ-МАССИВА ]

ИНДЕКСЫ-МАССИВА::= СПИСОК-ВЫРАЖЕНИЙ

Значением ПЕРВИЧНОГО-ВЫРАЖЕНИЯ является переменная типа “массив”. Значения ИНДЕКСОВ-МАССИВА должны принадлежать типам индексов соответствующего типа массива.

ПОЛЕ-ПЕРЕМЕННОЙ::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ. ИМЯ-ПОЛЯ

Значением ПЕРВИЧНОГО-ВЫРАЖЕНИЯ является переменная типа “структура”.

ИМЯ-ПОЛЯ::= ИДЕНТИФИКАТОР

ПЕРЕМЕННАЯ-КЛАССА::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ. ПЕРЕМЕННАЯ

Значением ПЕРВИЧНОГО-ВЫРАЖЕНИЯ является переменная типа “класс”.

МУЛЬТИПЕРЕМЕННАЯ::= | СПИСОК-ПЕРЕМЕННЫХ | |

СПИСОК-ПЕРЕМЕННЫХ

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

СПИСОК-ПЕРЕМЕННЫХ::= ПЕРЕМЕННАЯ [, СПИСОК-ПЕРЕМЕННЫХ ]

Мультипеременная определяет упорядоченный набор переменных. Число переменных в наборе должно быть больше 1.

АГРЕГАТ::= АГРЕГАТ-СТРУКТУРА | АГРЕГАТ-МАССИВ |

АГРЕГАТ-МНОЖЕСТВО | АГРЕГАТ-СПИСОК

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

АГРЕГАТ-СТРУКТУРА::= [ИЗОБРАЖЕНИЕ-ТИПА] ( [ЭЛЕМЕНТЫ-АГРЕГАТА] )

АГРЕГАТ-МАССИВ::= [ИЗОБРАЖЕНИЕ-ТИПА] [ [ЭЛЕМЕНТЫ-АГРЕГАТА] ]

АГРЕГАТ-МНОЖЕСТВО::= [ИЗОБРАЖЕНИЕ-ТИПА] { [ЭЛЕМЕНТЫ-АГРЕГАТА] }

АГРЕГАТ-СПИСОК::= [ИЗОБРАЖЕНИЕ-ТИПА] [[ ЭЛЕМЕНТЫ-АГРЕГАТА ]]

Агрегат [ ] обозначает пустой массив (когда верхняя граница индексов меньше нижней). Агрегат { } определяет пустое множество. Если пара скобок [[ или ]] встречается рядом при изображении АГРЕГАТ-МАССИВА, то соседние скобки дожны быть разделены пробелом.

ЭЛЕМЕНТЫ-АГРЕГАТА::= ЭЛЕМЕНТ-АГРЕГАТА [, ЭЛЕМЕНТЫ-АГРЕГАТА]

Значением агрегата является набор значений элементов агрегата, перечисленных в скобках. Агрегат может иметь иерархическую структуру, поскольку элементом агрегата может быть агрегат. Тип агрегата определяется типом позиции, в которой находится агрегат. Значение агрегата должно соответствовать типу позиции. Тип агрегата может быть указан явно ИЗОБРАЖЕНИЕМ-ТИПА - это не является необходимым, но может улучшить восприятие программы.

ЭЛЕМЕНТ-АГРЕГАТА::= [ИНДЕКС-ЭЛЕМЕНТА-АГРЕГАТА: ] ВЫРАЖЕНИЕ

ИНДЕКС-ЭЛЕМЕНТА-АГРЕГАТА::= ВЫРАЖЕНИЕ | ИМЯ-ПОЛЯ

Индексы элементов, если присутствуют, должны соответствовать индексам элементов массива или именам полей структуры.

type Ar4 = array (real, 1..4);

Ar4 x = [ 0, 1, 2, 3];

Пример 5. Задание агрегата

ГЕНЕРАТОР-ПРЕДИКАТА::=

predicate ОПИСАНИЕ-ПРЕДИКАТА

Исполнение генератора предиката создает новый предикат, операторная часть которого определяется телом предиката, находящегося в составе ОПИСАНИЯ-ПРЕДИКАТА; см. разд. 6.3.1. В теле предиката фиксируются значения свободных переменных (отличных от аргументов и результатов) на момент исполнения генератора. Новый предикат становится значением генератора предиката.


УНАРНОЕ-ВЫРАЖЕНИЕ::= УНАРНАЯ-ОПЕРАЦИЯ ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ

УНАРНАЯ-ОПЕРАЦИЯ::= + | - |! | ~

БИНАРНОЕ-ВЫРАЖЕНИЕ::= ВЫРАЖЕНИЕ БИНАРНАЯ-ОПЕРАЦИЯ ВЫРАЖЕНИЕ

БИНАРНАЯ-ОПЕРАЦИЯ::= * | / | % | + | - | << | >> | in |

< | > | <= | >= | = | != | & | ^ | or | xor | => | <=>

Семантика операций и их приоритеты определены ниже в таблице. Типы аргументов каждой операции должны соответствовать операции. Операция “+” для объединения массивов описана в разд. 6.8.4.

МОДИФИКАЦИЯ::= МОДИФИКАЦИЯ-СТРУКТУРЫ | МОДИФИКАЦИЯ-МАССИВА

МОДИФИКАЦИЯ-СТРУКТУРЫ::= ВЫРАЖЕНИЕ with АГРЕГАТ

МОДИФИКАЦИЯ-МАССИВА::=

ВЫРАЖЕНИЕ with АГРЕГАТ |

ВЫРАЖЕНИЕ with ОПРЕДЕЛЕНИЕ-МАССИВА-ПО-ЧАСТЯМ

В структурном значении выражения, обозначающего массив или структуру, меняются компоненты, представленные АГРЕГАТОМ или ОПРЕДЕЛЕНИЕМ-МАССИВА-ПО-ЧАСТЯМ (см. разд. 6.8.3). Значением операции является обновленный массив или структура.

type ar0_4 = array (int, 0..4);

ar0_4 ones = [ 1, 1, 1, 2, 1 ];

ar0_4 ones1 = ones [3: 1]; // [ 1, 1, 1, 1, 1 ]

type Vec(nat n) = array (real, 1..n);

perm(nat n, Vec(n) b, nat m, k: Vec(n) b')

{ b' = b with [k: b [m], m: b [k]] };

Пример 6. Замена части структурного значения

УСЛОВНОЕ-ВЫРАЖЕНИЕ::= ВЫРАЖЕНИЕ? ВЫРАЖЕНИЕ: ВЫРАЖЕНИЕ

Первое выражение имеет тип “логический”. Если первое ВЫРАЖЕНИЕ завершается илентификатором, то идентификатор и последующий символ “?” должны быть разделены пробелом.

МУЛЬТИВЫРАЖЕНИЕ::= | СПИСОК-ВЫРАЖЕНИЙ | |

СПИСОК-ВЫРАЖЕНИЙ

Значением мультивыражения является набор значений, получающихся в результате вычисления перечисленных выражений. Выражения вычисляются независимо, т. е. параллельно. Мультивыражение может находиться в правой части оператора присваивания, если в левой находится мультипеременная.

ВЫРАЖЕНИЕ::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ | УНАРНОЕ-ВЫРАЖЕНИЕ |

БИНАРНОЕ-ВЫРАЖЕНИЕ | УСЛОВНОЕ-ВЫРАЖЕНИЕ |

МУЛЬТИВЫРАЖЕНИЕ


Таблица 1. Операции в порядке уменьшения приоритета

^ Возведение в степень
+, -,!, ~ Унарные плюс и минус, логическое отрицание и поэлементное дополнение для множеств, побитовое дополнение для ограниченных целых
*, /, % Арифметическое умножение, деление и остаток от целочисленного деления
+, - Арифметическое сложение и вычитание; объединение и вычитание множеств; конкатенация строк; объединение массивов с непересекающимися типами индексов
<<, >> Побитовый (поэлементный) сдвиг влево и вправо для целых
<- Обновление элемента массива или поля структуры
in Проверка вхождения элемента в множество
<, >, <=, >= Операции арифметического сравнения
=,!= Проверка на равенство и неравенство
& Пересечение множеств, логическая конъюнкция, побитовое И для ограниченных целых
xor Симметрическая разность для множеств, исключительное ИЛИ для логических выражений и ограниченных целых (побитовое)
or Объединение множеств, логическая дизъюнкция, побитовое ИЛИ для ограниченных целых
=> Импликация
<=> Логическое тождество
?: Трёхместная условная операция

Типы

Всякая переменная имеет некоторый тип. Тип может быть атрибутом языковой конструкции. Семантика конструкции налагает определенные ограничения на значения типов. Для каждой подконструкции некоторой конструкции определяется позиция ее вхождения внутри конструкции. Это, например, позиции операндов операций, позиции правой и левой частей в операторе присваивания, позиция фактического параметра в вызове предиката и др. При наличии в конструкции двух позиций типы этих позиций должны быть согласованы. Частным случаем согласованности является совместимость типов. Например, тип выражения правой части оператора присваивания должен быть совместим с типом переменной левой части оператора присваивания, но не наоборот. Реализуется неявное преобразование (называемое приведением) значения совместимого типа к типу, требуемому позицией.

ОПИСАНИЕ-ТИПА::=

type ИМЯ-ТИПА [ ( ПАРАМЕТРЫ-ТИПА ) ] = ИЗОБРАЖЕНИЕ-ТИПА |

ПРЕДОПИСАНИЕ-ТИПА

ИМЯ-ТИПА::= ИДЕНТИФИКАТОР

ПАРАМЕТРЫ-ТИПА::=

ИЗОБРАЖЕНИЕ-ТИПА [:blank:] ИДЕНТИФИКАТОР (, ИДЕНТИФИКАТОР)*

[, ПАРАМЕТРЫ-ТИПА]

Описание типа связывает имя типа с его изображением. Тип может быть параметризован, т. е. зависеть от набора значений переменных и типов, указанных в качестве параметров.

ПРЕДОПИСАНИЕ-ТИПА::= type ИМЯ-ТИПА

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


ИЗОБРАЖЕНИЕ-ТИПА::=

ИЗОБРАЖЕНИЕ-ПРИМИТИВНОГО-ТИПА | ИЗОБРАЖЕНИЕ-ТИПА-ПО-ИМЕНИ |

ИЗОБРАЖЕНИЕ-ТИПА-КАК-ПАРАМЕТРА | ИЗОБРАЖЕНИЕ-ТИПА-ПРЕДИКАТА |

ИЗОБРАЖЕНИЕ-ПОДТИПА | ИЗОБРАЖЕНИЕ-ПЕРЕЧИСЛЕНИЯ |

ИЗОБРАЖЕНИЕ-СТРУКТУРНОГО-ТИПА |

ИЗОБРАЖЕНИЕ-ТИПА-ОБЪЕДИНЕНИЯ

ИЗОБРАЖЕНИЕ-ПРИМИТИВНОГО-ТИПА::=

nat [ ( РАЗРЯДНОСТЬ-ЦЕЛЫХ ) ] |

int [ ( РАЗРЯДНОСТЬ-ЦЕЛЫХ ) ] |

real [ ( РАЗРЯДНОСТЬ-ВЕЩЕСТВЕННЫХ ) ] |

bool | char

Тип nat является подмножеством неотрицательных чисел типа int, char - множество символов некоторого алфавита. Конкретные представления примитивных типов даются в императивном расширении языка (см. разд. 6.11).

Разрядность определяет максимальное число битов в представлении значений типа. Указание разрядности в изображении примитивного типа является частью императивного расширения языка.

Значения типа nat совместимы с типом int, а int - с типом real. Значения типа меньшей размерности совместимы с аналогичными типами большей размерности.

ИЗОБРАЖЕНИЕ-ТИПА-ПО-ИМЕНИ::= [ИМЯ-МОДУЛЯ. ] ИМЯ-ТИПА [ ( АРГУМЕНТЫ ) ]

Ранее определенный тип может быть представлен своим именем. Изображение параметризованного типа представляется с конкретными параметрами.

ИЗОБРАЖЕНИЕ-ТИПА-КАК-ПАРАМЕТРА::= type ИМЯ-ТИПА

Объявление типа в качестве параметра описания типа или определения предиката реализуется описателем type. В качестве обозначения типа может использоваться выражение типа type, которым, например, может являться параметр предиката или параметризованного типа. Например:

type Point (type T) = struct (T x, y);

type Polyline (type T) = list (Point (T));

decimate (type T, list (T) data: list (T) data') {

data' = (data = nil)?

nil:

data.car + (len(data) < 3? nil: decimate(T, data.cdr.cdr))

};

reverse (type T, list (T) data: list (T) data') {

data' = (data = nil)? nil: reverse (T, data.cdr) + data.car

};

Polyline (real) line = [[ (0.0, 0.0), (0.1, 0.2), (0.2, 0.5),

(0.3, 0.6), (0.4, 0.3), (0.5, 0.0) ]];

Polyline (real) line1 = reverse (decimate (real, line));

// [[ (0.4, 0.3), (0.2, 0.5), (0.0, 0.0) ]]

Пример 7. Использование типов в качестве параметров

В примере выше идентификатор T использован в качестве типа-параметра, а тип real - как фактический параметр.

squareVec (type T, list (T) data: list (T) data') {

data' = (data = nil)? nil: data.car ^ 2 + squareVec (T, data.cdr)

};

list (int) squares = squareVec (int, [[ 0, 1, 2, 3, 4 ]]); // [[ 0, 1, 4, 9, 16 ]]

Выше приведен еще один пример использования типа T в качестве параметра предиката.

ИЗОБРАЖЕНИЕ-ТИПА-ПРЕДИКАТА::=

predicate ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА

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

type int_list = list (int);

map_list (int_list src, predicate (int: int) func: int_list dest) {

dest = (src = nil)? nil: func (src.car) + map_list (src.cdr, func))

};

int_list numbers = [[ 0, 1, 2, 3, 4, 5 ]];

int_list squares = map_list (numbers, predicate (int a: int b) { b = a * a; });

// squares = [[ 0, 1, 4, 9, 16, 25 ]]

Пример 8. Использование предикатного типа

ОПРЕДЕЛЕНИЕ-ПОДТИПА::=

subtype ( ОПИСАНИЕ-ПЕРЕМЕННОЙ: ВЫРАЖЕНИЕ ) |

ИЗОБРАЖЕНИЕ-ДИАПАЗОНА

Конструкция subtype (T x: выражение) определяет подмножество типа T. Описание переменной x действует в пределах этой конструкции. Множество значений переменной x, для которых логическое выражение имеет значение “истина”, является определяемым подтипом типа T. Если выражение содержит другие переменные, то все они являются параметрами изображаемого типа. Конструкция ОПИСАНИЕ-ПЕРЕМЕННОЙ определена в разд. 6.3.3

ИЗОБРАЖЕНИЕ-ДИАПАЗОНА::= ВЫРАЖЕНИЕ .. ВЫРАЖЕНИЕ

Изображение диапазона является подмножеством типа int, enum или char. Изображение типа subtype (nat i: i >= 1 & i <= n + 1) эквивалентно изображению диапазона: 1.. n + 1.

type odd_t = subtype (int n: n % 2 = 1);

type diap10_20_t = 10..20;

ИЗОБРАЖЕНИЕ-СТРУКТУРНОГО-ТИПА::=

ИЗОБРАЖЕНИЕ-ТИПА-СТРУКТУРЫ | ИЗОБРАЖЕНИЕ-ТИПА-ОБЪЕДИНЕНИЯ |

ИЗОБРАЖЕНИЕ-ТИПА- СПИСКА | ИЗОБРАЖЕНИЕ-ТИПА-МНОЖЕСТВА |

ИЗОБРАЖЕНИЕ-ТИПА-МАССИВА

ИЗОБРАЖЕНИЕ-ТИПА-СТРУКТУРЫ::= struct ( ОПИСАНИЕ-ПОЛЕЙ )

ОПИСАНИЕ-ПОЛЕЙ::= ИЗОБРАЖЕНИЕ-ТИПА [:blank:] СПИСОК-ИМЕН-ПОЛЕЙ

[, ОПИСАНИЕ-ПОЛЕЙ]

СПИСОК-ИМЕН-ПОЛЕЙ::= ИМЯ-ПОЛЯ [, СПИСОК-ИМЕН-ПОЛЕЙ]

Значение типа структуры состоит из совокупности значений полей структуры. Имена полей должны быть различны. Число полей должно быть не менее двух.

type Point = struct (int x, y);

Point pt = (10, 20);

Пример 9. Определение структуры

ИЗОБРАЖЕНИЕ-ТИПА-ОБЪЕДИНЕНИЯ::= union ( ОПИСАНИЯ-КОНСТРУКТОРОВ )

ОПИСАНИЯ-КОНСТРУКТОРОВ::=

ОПИСАНИЕ-КОНСТРУКТОРА (, ОПИСАНИЕ-КОНСТРУКТОРА)*

Значением типа объединения является значение одного из конструкторов, перечисленных в списке описаний конструкторов. Число конструкторов должно быть не меньше двух.

ОПИСАНИЕ-КОНСТРУКТОРА::= ИМЯ-КОНСТРУКТОРА [ ( ОПИСАНИЕ-ПОЛЕЙ ) ]

ИМЯ-КОНСТРУКТОРА::= ИДЕНТИФИКАТОР

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

Работа с объектами типа объединения реализуется с помощью следующих конструкций: конструктор, распознаватель и поле объединения. Все они являются ПЕРВИЧНЫМИ-ВЫРАЖЕНИЯМИ (см. разд. 6.6).

КОНСТРУКТОР::= ИМЯ-КОНСТРУКТОРА [ (СПИСОК-ВЫРАЖЕНИЙ) ]

Выражения, подставляемые в качестве аргументов КОНСТРУКТОРА, по их числу и типам должны соответствовать ОПИСАНИЯМ-ПОЛЕЙ в соответствующем ОПИСАНИИ-КОНСТРУКТОРА. Правила соответствия такие же, как для вызова предиката. Значением конструкции КОНСТРУКТОР является имя конструктора вместе со значениями его аргументов, если аргументы присутствуют.

РАСПОЗНАВАТЕЛЬ::= ИМЯ-РАСПОЗНАВАТЕЛЯ ( ВЫРАЖЕНИЕ )

ИМЯ-РАСПОЗНАВАТЕЛЯ::= ИМЯ-КОНСТРУКТОРА?

Символ “?” является частью имени распознавателя и пишется слитно с именем конструктора, без пробела. ВЫРАЖЕНИЕ имеет тип объединения. Распознаватель является функцией типа bool. Значение РАСПОЗНАВАТЕЛЯ истинно, если значением ВЫРАЖЕНИЯ является конструктор с именем ИМЯ-КОНСТРУКТОРА.

ПОЛЕ-ОБЪЕДИНЕНИЯ::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ. ИМЯ-ПОЛЯ

Значением ПЕРВИЧНОГО-ВЫРАЖЕНИЯ является переменная типа «объединение». Значением ПОЛЯ-ОБЪЕДИНЕНИЯ является значение поля с именем ИМЯ-ПОЛЯ в структуре переменной типа «объединение». Использование конструкции ПОЛЕ-ОБЪЕДИНЕНИЯ корректно лишь в случае истинности распознавателя ИМЯ-КОНСТРУКТОРА?(ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ) для конструктора, к которому относится поле с именем ИМЯ-ПОЛЯ, в противном случае исполнение конструкции не определено.

Имена конструкторов и распознавателей являются глобально определенными в теле модуля, содержащего ИЗОБРАЖЕНИЕ-ТИПА-ОБЪЕДИНЕНИЯ.

ОПРЕДЕЛЕНИЕ-КОНСТРУКТОРА::=

ИМЯ-КОНСТРУКТОРА [ ( ОПРЕДЕЛЕНИЕ-ПОЛЕЙ-КОНСТРУКТОРА ) ]

ОПРЕДЕЛЕНИЕ-ПОЛЕЙ-КОНСТРУКТОРА::=

ОПРЕДЕЛЕНИЕ-ПОЛЯ-КОНСТРУКТОРА

[, ОПРЕДЕЛЕНИЕ-ПОЛЕЙ-КОНСТРУКТОРА]

ОПРЕДЕЛЕНИЕ-ПОЛЯ-КОНСТРУКТОРА::=

[ИЗОБРАЖЕНИЕ-ТИПА-ПЕРЕМЕННОЙ] ИДЕНТИФИКАТОР

Конструкция ОПРЕДЕЛЕНИЕ-КОНСТРУКТОРА используется в качестве
АЛЬТЕРНАТИВЫ после case в операторе выбора (см. разд. 6.5) для выражения типа объединения. Значением АЛЬТЕРНАТИВЫ является конструктор с именем ИМЯ-КОНСТРУКТОРА и набором переменных, обозначающих поля данного конструктора. Эти переменные являются локальными в ОПЕРАТОРЕ-АЛЬТЕРНАТИВЫ, исполняемом для данной АЛЬТЕРНАТИВЫ. Типы переменных могут не указываться, поскольку они определяются из ИЗОБРАЖЕНИЯ-ТИПА-ОБЪЕДИНЕНИЯ.


type int_tree = union (

leaf (int val),

node (int_tree lhs, int v, int_tree rhs)

);

int_tree foo;

//...

switch (foo) {

case leaf(v0): print("leaf", v0)

case node(l, v1, r): print("node with ", v1)

};

int_tree one_leaf = leaf(42);

int_tree small_tree = node(leaf(1), 2, node(leaf(3), 4, leaf(5)));

// small_tree задаёт следующее дерево:

// 2

// / \

// 1 4

// / \

// 3 5

Пример 10. Использование объединений

ИЗОБРАЖЕНИЕ-ПЕРЕЧИСЛЕНИЯ::=

enum ( ИДЕНТИФИКАТОР (, ИДЕНТИФИКАТОР)* )

Тип перечисления является частным случаем типа объединения с конструкторами без аргументов. Описатель enum трактуется как эквивалент union.

type fruit = enum (apple, orange, banana);

Пример 11. Описание перечисления

Структура вида “список” представляется как упорядоченная совокупность однородных элементов. Тип списка из элементов типа T определяется следующим описанием:

type list (type T) = union (

nil,

cons (T car, list(T) cdr)

);

Тип list считается определенным в языке P и не требует описания в программе. Имена list, nil и cons глобально определены в предикатной прграмме.

Конструктор nil определяет пустой список, не содержащий элементов. Остальные значения типа list представляются конструктором cons(x, s), где элемент x есть первый элемент списка - голова списка, а s есть оставшаяся часть списка - хвост списка. Функция len(s) определяет число элементов списка s. Операция конкатенации s1 + s2 определяет список, состоящий из элементов списка s1, за которыми следуют элементы списка s2. Аргументами конкатенации могут быть также элементы списка. Функция last(s) определяет последний элемент непустого списка s; функция prec(s) - оставшуюся часть списка без последнего элемента.

ЭЛЕМЕНТ-СПИСКА::= ПЕРВИЧНОЕ-ВЫРАЖЕНИЕ [ ИНДЕКС-ЭЛЕМЕНТА ]

Данная конструкция определяет значение элемента с указанным индексом в списке. Значением ПЕРВИЧНОГО-ВЫРАЖЕНИЯ является список.

ИНДЕКС-ЭЛЕМЕНТА::= ВЫРАЖЕНИЕ

Для списка s конструкция s[i] определяет i-й элемент. Допустимыми являются значения индекса i от 0 до len(s) - 1.

type int_list = list (int);

int_list s = [[ 1, 1, 2, 3, 5, 8 ]];

int s_car = s.car; // s_car = 1

int_list s_cdr = s.cdr; // s_cdr = [[ 1, 2, 3, 5, 8 ]]

int_list ss = s + [[ 13, 21 ]]; // ss = [[ 1, 1, 2, 3, 5, 8, 13, 21 ]]

int count = len (s); // count = 6

int e = s[3]; // e = 3

Пример 12. Операции со списком

СТРОКОВЫЙ-ТИП::= string

Строковый тип string является обозначением типа списка list(char). В дополнение к определенным выше операциям со списками имеется возможность задания конкретного значения строкового типа в виде строковой константы (см. разд. 6.2).

ИЗОБРАЖЕНИЕ-ТИПА-МНОЖЕСТВА::= set ( ИЗОБРАЖЕНИЕ-БАЗОВОГО-ТИПА )

ИЗОБРАЖЕНИЕ-БАЗОВОГО-ТИПА::= ИЗОБРАЖЕНИЕ-ТИПА

Тип множества есть множество всех подмножеств некоторого конечного базового типа. Имеется унарная операция ~ дополнения множества. Определены: операция «+» сложения множеств, операция «-» вычитания множеств, а также вычитания элемента из множества, операция & пересечения множеств, операция or объединения множеств, операция in принадлежности элемента множеству (см. разд. 6.6). Число элементов в множестве реализуется функцией len.

Операция mask преобразует множество в целое значение. Операция bits реализует обратную операцию преобразования целого в множество.

type int_set_t = set (1..1000);

int_set_t pow_2 = { 0, 2, 4, 8, 16, 32 };

bool is_pow_2 = 4 in pow_2; // is_pow_2 = true

int_set_t more_pow_2 = pow_2 + { 64, 128 };

Пример 13. Использование множеств





Дата публикования: 2014-11-18; Прочитано: 247 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.028 с)...