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

Язык РЕФАЛ: первичные функции и примеры составления программ

< Лекция 3 || Лекция 4: 12 || Лекция 5 >
Аннотация: Первичные функции Рефала-2: функции ввода/вывода; арифметические функции; функции лексического анализа; функции для работы с символами-метками. Синтаксический анализатор для языка арифметических выражений: описание синтаксиса языка формами Бэкуса-Наура; программа анализатора и ее близость к языку БНФ. Программа суммирования последовательности чисел и ее особенности.

Первичные функции

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

Функции ввода/вывода

Функции ввода/вывода предназначены для организации диалогового взаимодействия между пользователем и программой. Для ввода строки с клавиатуры используется функция card. Для вывода информации на экран используются операции print, prout, которые различаются возвращаемым значением и способом представления информации на экране. Ввод/вывод может быть переназначен в произвольный файл стандартным образом.

Функция card осуществляется вызовом

k/card/ .

и дает возможность читать строку символов из входного потока. После вызова функции программа переходит в состояние ожидания ввода строки. По окончании ввода строки следует нажать клавишу "Enter". Возвращаемым значением является введенная строка.

Функция print осуществляется вызовом

k/print/ <E>.

где E - произвольное рефал-выражение (возможно, и пустое), и выводит c новой строки это выражение. При пустом выражении пропускается 1 печатная строка. При непустом выражении символы-литеры выводятся в виде соответствующих литер, структурные скобки выводятся как круглые скобки, а составные символы выводятся с ограничителями ' вместо "/". Возвращаемым значением является выводимое выражение.

Например, функция

k/print/ 'функция'(/f1/).

возвратит выражение

'функция'(/f1/).

При этом на устройство вывода будет выдана строка

'функция'('f1') ,

Функция prout осуществляется вызовом

k/prout/ <E>.

где E - произвольное рефал-выражение (возможно, и пустое), и выводит c новой строки это выражение. Отличием от функции print является то, что всегда возвращается пустое выражение.

Арифметические функции

Функции работают только с целыми числами, каковыми являются в представлении Рефала - символы-числа с возможно предшествующим знаком минус '-'. Например, '-'/7/, /0/, /2007/. Нуль представляется либо нулевым символом-числом, либо пустым выражением.

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

К арифметическим функциям относятся:

  • add - сложение;
  • mul - умножение;
  • sub - вычитание;
  • dr - деление нацело с остатком;
  • div - деление нацело;
  • p1 - инкремент (увеличение на 1);
  • m1 - декремент (уменьшение на 1).

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

Функции add, mul, sub осуществляются вызовом

k/op/ (<N1>) <N2>. ,

где op - одна из операций add, mul, sub, а N1 и N2 - макроцифры. Этот вызов возвращает макроцифру (для положительного результата знак '+' не ставится) суммы, произведения или разности N1-N2 в зависимости от операции. Например, следующие вызовы функции приведут к таким результатам:

k/add/  ('-'/5/)   /3/.   ->   '-'/2/ 
k/add/        ()   /2/.   ->      /2/    
k/mul/  ('-'/5/)   /3/.   ->  '-'/15/   
k/mul/     (/2/).         ->      /0/    
k/sub/  ('-'/5/)   /3/.   ->      /8/   
k/sub/        ()   /2/.   ->   '-'/2/

Функция dr осуществляется вызовом

k/dr/ (<N1>) <N2>.    ,

где N1 - делимое, а N2 - делитель. Она возвращает выражение

<Q> (<R>) ,

где Q - частное, а R - остаток. Попытка делить на 0 приводит к аварийному завершению. Знаки частного и остатка определяются следующим образом: сначала производится деление нацело без учета знаков делимого и делителя, а затем частному и остатку приписываются знаки так, чтобы выполнялось соотношение:

N1 = Q*N2 + R

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

k/dr/    (/5/)    /3/.  ->     /1/    (/2/)
k/dr/    (/5/) '–'/3/.  ->  '–'/1/    (/2/)
k/dr/ ('–'/5/)    /3/.  ->  '–'/1/ '–'(/2/)
k/dr/ ('–'/5/) '–'/3/.  ->     /1/ '–'(/2/)

Функция div в отличие от функции dr возвращает только частное. В остальном же подобна ей. Например, следующие вызовы функции приведут к таким результатам:

k/div/    (/5/)    /3/.  ->    /1/
k/div/    (/5/) '–'/3/.  -> '–'/1/
k/div/ ('–'/5/)    /3/.  -> '–'/1/
k/div/ ('–'/5/) '–'/3/.  ->    /1/

Функции p1, m1 имеют 1 аргумент и возвращают соответственно макроцифру, увеличенную на 1 или уменьшенную на 1. Например, следующие вызовы приведут к таким результатам:

k/p1/  '–'/2007/.   ->  '–' /2006/
k/p1/.              ->         /1/
k/m1/     /2007/.   ->      /2006/
k/m1/.              ->      '–'/1/

Функция symb преобразует макроцифру (аргумент) в символьное представление. Например, следующие вызовы функции приведут к таким результатам:

k/symb/  '–'/2007/.  ->  '–2007'
k/symb/.             ->      '0'

Функция numb преобразует цепочку символов (аргумент), являющуюся десятичной записью целого числа в макроцифру этого числа. Например, следующие вызовы функции приведут к таким результатам:

k/numb/  '–2007'.  ->  '–'/2007/
k/numb/      '0'.  ->        /0/
< Лекция 3 || Лекция 4: 12 || Лекция 5 >