Как начинался компьютер
Компьютерная революция
Двоичный код
Разработки военных лет
Интегральные микросхемы
Микрокомпьютер
Персоны
Сеть
Язык компьютера
Развитие ПО
Гибкие системы
Средства разработки
Информатика
Вычислительная наука
Операционные системы
Искусственный интеллект
Предыстория
Поиск
Знания и рассуждения
Логика
Робототехника
 

 
Язык программирования Оберон-2 Печать

Оберон-2 - язык программирования общего назначения, продолжающий традицию языков Паскаль и Modula-2. Его основные черты - блочная структура, модульность, раздельная компиляция, статическая типизация со строгим контролем соответствия типов (в том числе межмодульным), а также расширение типов и связанные с типами процедуры.

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

Синтаксис

Для описания синтаксиса Оберона-2 используются Расширенные Бэкуса-Наура Формы (РБНФ). Варианты разделяются знаком |. Квадратные скобки [ и ] означают необязательность записанного внутри них выражения, а фигурные скобки { и } означают его повторение (возможно 0 раз). Нетерминальные символы начинаются с заглавной буквы (например, Оператор). Терминальные символы или начинаются малой буквой (например, идент), или записываются целиком заглавными буквами (например, BEGIN), или заключаются в кавычки (например, ":=").

Словарь и представление

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

Идентификаторы - последовательности букв и цифр. Первый символ должен быть буквой. идент = буква {буква | цифра}. Примеры: x Scan Oberon2 GetSymbol firstLetter

Числа - целые или вещественные (без знака) константы. Типом целочисленной константы считается минимальный тип, которому принадлежит ее значение. Если константа заканчивается буквой H, она является шестнадцатеричной, иначе - десятичной.

Вещественное число всегда содержит десятичную точку. Оно может также содержать десятичный порядок. Буква E (или D) означает "умножить на десять в степени". Вещественное число относится к типу REAL кроме случая, когда у него есть порядок, содержащий букву D. В этом случае оно относится к типу LONGREAL.

      число          =         целое | вещественное.

      целое          =         цифра {цифра} | цифра {шестнЦифра} "H".

      вещественное         =         цифра {цифра} "." {цифра} [Порядок].

      Порядок      =         ("E" | "D") ["+" | "-"] цифра {цифра}.

      шестнЦифра           =         цифра | "A" | "B" | "C" | "D" | "E" | "F".

      цифра         =         "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9".

Примеры: 

      1991           INTEGER          1991

      0DH           SHORTINT        13

      12.3           REAL   12.3

      4.567E8      REAL   456700000

      0.57712566D-6        LONGREAL      0.00000057712566

Символьные константы обозначаются порядковым номером символа в шестнадцатеричной записи, оканчивающейся буквой X. символ = цифра {шестнЦифра} "X".

Строки - последовательности символов, заключенные в одиночные (') или двойные (") кавычки. Открывающая кавычка должна быть такой же, что и закрывающая и не должна встречаться внутри строки. Число символов в строке называется ее длиной. Строка длины 1 может использоваться везде, где допустима символьная константа и наоборот.

      строка = ' " ' {символ} ' " ' | " ' " {символ} " ' ".

Примеры: "Oberon-2"    "Don't worry!"    "x"

Операции и разделители - это специальные символы, пары символов или зарезервированные слова, перечисленные ниже. Зарезервированные слова состоят исключительно из заглавных букв и не могут использоваться как идентификаторы.

+          :=        IMPORT           ARRAY            RETURN

-           ^           BEGIN IN         THEN

*           =          BY       IS         TO

/           #          CASE   LOOP   TYPE

~          <          CONST             MOD    UNTIL

&          >          DIV       MODULE          VAR

.           <=        DO       NIL       WHILE

,           >=        ELSE   OF       WITH

;           ..          ELSIF   OR      

|           :           END     POINTER         

(           )           EXIT     PROCEDURE              

[           ]           FOR     RECORD         

{           }           IF         REPEAT

Комментарии могут быть вставлены между любыми двумя словами программы. Это произвольные последовательности символов, начинающиеся скобкой (* и оканчивающиеся *). Комментарии могут быть вложенными. Они не влияют на смысл программы.

Объявления и области действия

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

Область действия объекта x распространяется текстуально от точки его объявления до конца блока (модуля, процедуры или записи), в котором находится объявление. Для этого блока объект является локальным. Это разделяет области действия одинаково именованных объектов, которые объявлены во вложенных блоках. Правила для областей действия таковы:

  1. Идентификатор не может обозначать больше чем один объект внутри данной области действия (то есть один и тот же идентификатор не может быть объявлен в блоке дважды);
  2. Ссылаться на объект можно только изнутри его области действия;
  3. Тип T вида POINTER TO T1 может быть объявлен в точке, где T1 еще неизвестен. Объявление T1 должно следовать в том же блоке, в котором T является локальным;
  4. Идентификаторы, обозначающие поля записи или процедуры, связанные с типом, могут употребляться только в обозначениях записи.

Идентификатор, объявленный в блоке модуля, может сопровождаться при своем объявлении экспортной меткой ("*" или "-"), чтобы указать, что он экспортируется. Идентификатор x, экспортируемый модулем M, может использоваться в других модулях, если они импортируют M (см. гл. 11). Тогда идентификатор обозначается в этих модулях М.x и называется уточненным идентификатором. Переменные и поля записей, помеченные знаком "-" в их объявлении, предназначены только для чтения в модулях-импортерах.

      УточнИдент            =          [идент "."] идент.

      ИдентОпр   =          идент ["*" | "-"].

Объявления констант

Объявление константы связывает ее идентификатор с ее значением.

      ОбъявлениеКонстанты        =         ИдентОпр "=" КонстантноеВыражение.

      КонстантноеВыражение      =         Выражение.

Константное выражение - это выражение, которое может быть вычислено по его тексту без фактического выполнения программы. Его операнды - константы (Гл. 8) или стандартные функции, которые могут быть вычислены во время компиляции.

Примеры объявлений констант:

      N = 100

      limit = 2*N - 1

      fullSet = {MIN(SET) .. MAX(SET)}

Объявления типа

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

Тип массив

Массив - структура, состоящая из определенного количества элементов одинакового типа, называемого типом элементов. Число элементов массива называется его длиной. Элементы массива обозначаются индексами, которые являются целыми числами от 0 до длины массива минус 1.

Тип запись

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

Тип указатель

Переменные-указатели типа P принимают в качестве значений указатели на переменные некоторого типа T. T называется базовым типом указателя типа P и должен быть типом массив или запись. Типы указатель заимствуют отношение расширения своих базовых типов: если тип T1 - расширение T и P1 - это тип POINTER TO T1, то P1 также является расширением P.

      ТипУказатель = POINTER TO Тип.

Если p - переменная типа P = POINTER TO T, вызов стандартной процедуры NEW(p) размещает переменную типа T в свободной памяти. Если T - тип запись или тип массив с фиксированной длиной, размещение должно быть выполнено вызовом NEW(p); если тип T - n-мерный открытый массив, размещение должно быть выполнено вызовом NEW(p, e0, ..., en-1), чтобы T был размещен с длинами, заданными выражениями e0, ..., en-1. В любом случае указатель на размещенную переменную присваивается p. Переменная p имеет тип P. Переменная p^ (динамическая переменная), на которую ссылается p, имеет тип T. Любая переменная-указатель может принимать значение NIL, которое не указывает ни на какую переменную вообще.

Объявления переменных

Объявления переменных дают описание переменных, определяя идентификатор и тип данных для них.

      ОбъявлениеПеременных = СписокИдент ":" Тип.

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

Выражения

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

Операнды

За исключением конструкторов множества и литералов (чисел, символьных констант или строк), операнды представлены обозначениями. Обозначение содержит идентификатор константы, переменной или процедуры. Этот идентификатор может быть уточнен именем модуля и может сопровождаться селекторами, если обозначенный объект - элемент структуры.

Операции

В выражениях синтаксически различаются четыре класса операций с разными приоритетами (порядком выполнения). Операция ~ имеет самый высокий приоритет, далее следуют операции типа умножения, операции типа сложения и отношения. Операции одного приоритета выполняются слева направо. Например, x-y-z означает (x- y) -z.

Логические операции

OR       логическая дизъюнкция           p OR q             "если p, то TRUE, иначе q"

&          логическая конъюнкция           p & q    "если p то q, иначе FALSE"

~          отрицание        ~p        "не p"

Эти операции применимы к операндам типа BOOLEAN и дают результат типа BOOLEAN.

Арифметические операции

+          сумма - разность

*           произведение

/           вещественное деление

DIV       деление нацело

MOD                остаток

Операции +, -, *, и / применимы к операндам числовых типов. Тип их результата - тип того операнда, который поглощает тип другого операнда, кроме деления (/), чей результат - наименьший вещественный тип, который поглощает типы обоих операндов. При использовании в качестве одноместной операции "-" обозначает перемену знака, а "+" - тождественную операцию. Операции DIV и MOD применимы только к целочисленным операндам.

Операции над множествами

+     объединение

-      разность (x - y = x * (-y))

*      пересечение

/      симметрическая разность множеств (x / y = (x-y) + (y-x))

Эти операции применимы к операндам типа SET и дают результат типа SET. Одноместный "минус" обозначает дополнение x, то есть -x это множество целых между 0 и MAX(SET), которые не являются элементами x. Операции с множествами не ассоциативны ((a+b)-c # a+(b-c)). Конструктор множества задает значение множества списком элементов, заключенным в фигурные скобки. Элементы должны быть целыми в диапазоне 0..MAX(SET). Диапазон a..b обозначает все целые числа в интервале [a, b].

Операторы

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

      Оператор =

           [Присваивание | ВызовПроцедуры

           | ОператорIf | ОператорCase | ОператорWhile | ОператорRepeat

           | ОператорFor | ОператорLoop | ОператорWith

           | EXIT | RETURN [Выражение]].

Вызовы процедур

Вызов процедуры активирует процедуру. Он может содержать список фактических параметров, которые заменяют соответствующие формальные параметры, определенные в объявлении процедуры. Соответствие устанавливается в порядке следования параметров в списках фактических и формальных параметров. Имеются два вида параметров: параметры-переменные и параметры-значения.

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

      ВызовПроцедуры = Обозначение [ФактическиеПараметры].

Последовательность операторов

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

Операторы If

Операторы if задают условное выполнение входящих в них последовательностей операторов. Логическое выражение, предшествующие последовательности операторов, будем называть условием (в оригинале - guard. Прим. перев.) Условия проверяются последовательно одно за другим, пока очередное не окажется равным TRUE, после чего выполняется связанная с этим условием последовательность операторов. Если ни одно условие не удовлетворено, выполняется последовательность операторов, записанная после слова ELSE, если оно имеется.

Операторы Case

Операторы case определяют выбор и выполнение последовательности операторов по значению выражения. Сначала вычисляется выбирающее выражение, а затем выполняется та последовательность операторов, чей список меток варианта содержит полученное значение. Выбирающее выражение должно быть такого целого типа, который поглощает типы всех меток вариантов, или и выбирающее выражение и метки вариантов должны иметь тип CHAR. Метки варианта - константы, и ни одно из их значений не должно употребляться больше одного раза. Если значение выражения не совпадает с меткой ни одного из вариантов, выбирается последовательность операторов после слова ELSE, если оно есть, иначе программа прерывается.

Операторы While

Операторы while задают повторное выполнение последовательности операторов, пока логическое выражение (условие) остается равным TRUE. Условие проверяется перед каждым выполнением последовательности операторов.

Операторы Repeat

Оператор repeat определяет повторное выполнение последовательности операторов пока условие, заданное логическим выражением, не удовлетворено. Последовательность операторов выполняется по крайней мере один раз.

Операторы For

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

Операторы Loop

Оператор loop определяет повторное выполнение последовательности операторов. Он завершается после выполнения оператора выхода внутри этой последовательности.

Операторы With

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

Объявления процедур

Объявление процедуры состоит из заголовка процедуры и тела процедуры. Заголовок определяет имя процедуры и формальные параметры. Для связанных с типом процедур в объявлении также определяется параметр-приемник. Тело содержит объявления и операторы. Имя процедуры повторяется в конце объявления процедуры.

Имеются два вида процедур: собственно процедуры и процедуры- функции. Последние активизируются обозначением функции как часть выражения и возвращают результат, который является операндом выражения. Собственно процедуры активизируются вызовом процедуры. Процедура является процедурой-функцией, если ее формальные параметры задают тип результата. Тело процедуры-функции должно содержать оператор возврата, который определяет результат.

Все константы, переменные, типы и процедуры, объявленные внутри тела процедуры, локальны в процедуре. Поскольку процедуры тоже могут быть объявлены как локальные объекты, объявления процедур могут быть вложенными. Вызов процедуры изнутри ее объявления подразумевает рекурсивную активацию.

Объекты, объявленные в окружении процедуры, также видимы в тех частях процедуры, в которых они не перекрыты локально объявленным объектом с тем же самым именем.

Формальные параметры

Формальные параметры - идентификаторы, объявленные в списке формальных параметров процедуры. Им соответствуют фактические параметры, которые задаются при вызове процедуры. Подстановка фактических параметров вместо формальных происходит при вызове процедуры. Имеются два вида параметров: параметры-значения и параметры-переменные, обозначаемые в списке формальных параметров отсутствием или наличием ключевого слова VAR. Параметры-значения это локальные переменные, которым в качестве начального присваивается значение соответствующего фактического параметра. Параметры-переменные соответствуют фактическим параметрам, которые являются переменными, и означают эти переменные. Область действия формального параметра простирается от его объявления до конца блока процедуры, в котором он объявлен. Процедура-функция без параметров должна иметь пустой список параметров. Она должна вызываться обозначением функции, чей список фактических параметров также пуст.

Модули

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

      Модуль       =         MODULE идент ";" [СписокИмпорта] ПоследовательностьОбъявлений

      [BEGIN ПоследовательностьОператоров] END идент ".".

      СписокИмпорта       =         IMPORT Импорт {"," Импорт} ";".

      Импорт        =         [идент ":="] идент.

Список импорта определяет имена импортируемых модулей. Если модуль A импортируется модулем M, и A экспортирует идентификатор x, то x упоминается внутри M как A.x. Если A импортируется как B:=A, объект x должен вызываться как B.x. Это позволяет использовать короткие имена-псевдонимы в уточненных идентификаторах. Модуль не должен импортировать себя. Идентификаторы, которые экспортируются (то есть должны быть видимы в модулях-импортерах) нужно отметить экспортной меткой в их объявлении.