Ярославский Государственный Университет им. П.Г. Демидова
Опубликован: 06.11.2008 | Доступ: свободный | Студентов: 988 / 62 | Оценка: 4.50 / 4.00 | Длительность: 10:47:00
Лекция 2:

Язык РЕФАЛ: простейшие конструкции Рефала-2

< Лекция 1 || Лекция 2: 12 || Лекция 3 >

Рефал-функции

Вызов рефал-функции описывается как функциональный терм и имеет следующий синтаксис:

k/<{имя функции}>/<{выражение-аргументов}>.

При этом в выражении аргументов выражения каждого из аргументов (если их несколько) разделяются пробелами.

Описание рефал-функции имеет следующий синтаксис:

<имя функции>
      <рефал-предложение 1>
      <рефал-предложение 2>
      .....................
      <рефал-предложение n>

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

Рефал-предложение имеет следующий синтаксис:

<рефал-выражение 1>=<рефал-выражение 2>

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

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

S -переменные - их значением могут быть только символы;

W -переменные - их значением могут быть только термы;

V -переменные - их значением могут быть только непустые выражения;

E -переменные - их значением могут быть любые выражения (в том числе и пустые).

Заметим, что имеется вложенность множеств переменных:

любая S -переменная является также W -переменной, а любая W -переменная является также V -переменной, и, наконец, любая V -переменная является также E -переменной.

Любая переменная имеет следующий вид:

<признак типа> [<спецификация>] <индекс>,

где признак типа - одна из четырех букв "S", "W", "V", "E", определяющая тип переменной, а индекс является цифрой или буквой и служит для отличия различных переменных в одном рефал-предложении. Например, S1, SA, Wx, V2, E3 - 5 переменных.

Спецификация определяет ограничение на множество значений переменных при поиске интерпретации. Если она отсутствует, то переменная может принимать любые значения, соответствующие типу переменной. Так, в предыдущем примере переменные S1 и SA могут принимать значения любого из символов, переменная Wx может принимать значения любого символа, числа, имени, ссылки или любого терма, переменная V2 - значение любого непустого выражения, а переменная E3 - также и значение пустого выражения.

Правила определения спецификаций мы рассмотрим в следующем разделе. А пока приведем несколько примеров.

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

k/First-symbol/    'Z'('AB')'+F'.

она должна возвратить символ 'Z'. "Решение", основанное на таком виде аргумента, будет следующим:

First-symbol    S1 Ex = S1

поскольку возможна единственная интерпретация переменных:

S1 <- 'Z'
Ex <- ('AB')'+F'.

Это решение для вызова

k/First-symbol/     /123/'+F'.

возвратит число /123/. Однако, если аргументом вызова функции будет рефал-выражение ('AB')'+F', не найдется ни одной интерпретации, так как структурная скобка "(" не является символом '('. Поэтому правильное решение нужно дополнить предварительным снятием структурных скобок, которые могут присутствовать в выражении аргумента (этого делать было бы не надо, если бы выражение аргумента имело, например, ограничение: отсутствуют структурные скобки). Приведем такое решение:

First-symbol      S1  Ex = S1
                 (E1) Ex = k/First-symbol/E1  Ex.
                         =

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

Пример 2. Для следующего вызова функции F

k/F/    'A1:=B1;A2:=B2;A3:=B3'.

имеется следующее ее описание:

F    E1 ';' E2 = k/G/ E1.   k/F/ E2.

Это означает, что выражение аргумента делится на 2 выражения, первое из которых обрабатывается функцией G, а второе - той же функцией F. Но при отождествлении левой части рефал-предложения с выражением аргумента возможны 2 интерпретации:

E1 <- 'A1:=B1'
E2 <- 'A2:=B2;A3:=B3'

и

E1 <- 'A1:=B1;A2:=B2'
E2 <- 'A3:=B3'

Такая неоднозначность может возникать в случае, когда рефал-предложение имеет несколько переменных типов V и E (назовем такие переменные VE -переменными). Для устранения неоднозначности используются 2 метода отождествления: слева направо и справа налево.

При отождествлении слева направо выбирается интерпретация, при которой самая левая VE -переменная принимает самое короткое значение. Если это не устранит неоднозначности, то так же производится интерпретация для второй и т.д. переменных. В примере 2 будет в этом случае выбрана первая интерпретация. Этот метод отождествления применяется по умолчанию. Функция F после первого применения выдаст результат:

k/G/ 'A1:=B1'.    k/F/ 'A2:=B2;A3:=B3'.

При отождествлении справа налево выбирается интерпретация, при которой самая правая VE-переменная принимает самое короткое значение. Если это не устранит неоднозначности, то так же производится интерпретация для второй и т.д. переменных. В примере 2 будет в этом случае выбрана вторая интерпретация. Для указания отождествления справа налево необходимо перед левой частью рефал-предложения поместить ключевое слово "R" (знак R, за которым идет хотя бы 1 пробел). В примере 2 в этом случае следует написать:

F    R E1 ';' E2 = k/G/ E1.   k/F/ E2.

и результатом замены будет выражение

k/G/ 'A1:=B1;A2:=B2'.     k/F/ 'A3:=B3'.

Упражнения

  1. Разработайте рефал-функцию, которая возвращает последний символ аргумента, если он есть, или пустую строку в противном случае.
  2. Разработайте рефал-функцию, которая возвращает первый и последний символ аргумента, если они не совпадают, или пустую строку в противном случае.
  3. Разработайте рефал-функцию, которая возвращает цепочку символов, симметрично расположенных в аргументе относительно центра цепочки.
  4. Разработайте рефал-функцию, которая реверсирует цепочку символов (первый символ становится последним, второй - предпоследним и т.д.).
  5. Разработайте рефал-функцию, которая заменяет в цепочке символов аргумента все нечетные символы на символ '1', а все четные символы на символ '0'.
  6. Разработайте рефал-функцию, которая ликвидирует все структурные и функциональные скобки в выражении аргумента.
< Лекция 1 || Лекция 2: 12 || Лекция 3 >