Стеллецкий В.
Рефал/2

Полезные рефал-функции (написанные на рефале)

(в процессе написания)


 

 

 

 

 

 

 

 

 

 

 

 


вверх

a - стандартное начало программ, читающих входной файл


a =/0/k/b/k/G0A/..

Функция a читает первую строку входного файла F (определяется 2-м параметром, см. также ввод/вывод) при помощи функции G0A и обращается к функции b для построчной обработка файла.
Здесь /0/ (макроцифра 0) - длина выходного файла X (определяется 3-м параметром, см. также ввод/вывод). Обычно этот файл не используется, а выход программы записывается в выходной поток.

 

 

 

 

 

 

 

 

 

 

 

 


вверх

b - цикл чтения входного файла

Функция b читает входной файл F (определяется 2-м параметром, см. также ввод/вывод) при помощи функции G0A построчено до конца файла. С каждой строкой обращается к функции f.


b =
  e1sa=k/f/e1.k/b/k/G0A/..
Здесь sa - символ перевода строки (0A), которым заканчивается каждая строка файла (последняя строка файла тоже должна им заканчиваться).

 

 

 

 

 

 

 

 

 

 

 

 


вверх

pp - проверка строк выходного файла на пустоту


pp =
   e1=k/P/e1.

Функция pp в случае непустого выражения обращается к функции P для записи его в выходной поток.

 

 

 

 

 

 

 

 

 

 

 

 


вверх

pr - удаление лишних пробелов


pr ' 'e1=k/pr/e1.
   e1' '=k/pr/e1.
   e1'  'e2=k/pr/e1' 'e2.
   e1=e1

pr ' 'e1=k/pr/e1.
   e1' '=k/pr/e1.
   e1wt'  'e2=e1k/pr/wt' 'e2.
   e1=e1

PR ' 'e1=k/PR/e1.
   e1' '=k/PR/e1.
   e1=k/PR2/e1.
PR2 e1'  'e2=e1k/PR2/' 'e2.
    e1=e1

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

Второй вариант отличается тем, что не делается лишних просмотров начальной части выражения (кроме одного терма wt).

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

 

 

 

 

 

 

 

 

 

 

 

 


вверх

Пример программы на рефале


a =/0/k/b/k/G0A/..
b =
  e1sa=k/f/e1.k/b/k/G0A/..
f e1=k/pp/k/pr/e1..
pp =
   e1=k/P/e1.
pr ' 'e1=k/pr/e1.
   e1' '=k/pr/e1.
   e1'  'e2=k/pr/e1' 'e2.
   e1=e1

Приведенная программа читает входной файл F (определяется 2-м параметром, см. также ввод/вывод) и записывает в выходной поток строки этого файла с удаленными лишними пробелами. Пустые строки в выходной поток не пишутся.

Программа состоит из стандартных функций a, b, pp и pr, каждая из которых описана отдельно (жми на ссылки), а также функции f, которая выполняется для каждой прочитанной строки, и состоит в последовательном выполнении функций pr и pp Также здесь используются машинные процедуры G0A и P.

 

 

 

 

 

 

 

 

 

 

 

 


вверх

add - сложение чисел (в текстовом виде)


add (e1sa)e2sb=k/add1/(k/CVDN/K/ADDN/k/SUBN/sa'0'.k/SUBN/sb'0'...)(e1)e2.
    (e1)e2=e1e2
add1 (sr)e2=k/add/e2.sr
     (s0sr)w1e2=k/add/w1k/add/(e2)s0..sr

Приведенная функция add возвращает сумму двух чисел (любой точности), представленных в текстовом виде. При обращении первое число берется в скобки.

 

 

 

 

 

 

 

 

 

 

 

 


вверх

mul - умножение чисел (в текстовом виде)


mul (e1)v2s3=k/add/(k/mul/(e1'0')v2.)k/mul1/(e1)s3..
    (e1)s3=k/mul1/(e1)s3.
    (e1)='0'
mul1 (e1)'0'='0'
     (e1)'1'=e1
     (e1)'2'=k/add/(e1)e1.
     (e1s2)s3=k/mul1t/(k/CVDN/K/MULN/k/SUBN/s2'0'.k/SUBN/s3'0'...)(e1)s3.
     ()s3=
mul1t (e1)()s3=e1
      (s1s2)(e3)s4=k/add/(k/mul1/(e3)s4.)s1.s2 
      (  s2)(e3)s4=       k/mul1/(e3)s4.    s2 

Приведенная функция mul возвращает произведение двух чисел (любой точности), представленных в текстовом виде. При обращении первое число берется в скобки.
Используется функция add

 

 

 

 

 

 

 

 

 

 

 

 


вверх

ЗП - "запомнить" - заменить в копилке


ЗП    e1'='e2=k/ЗП1/k/ВК/e1..k/ЗК/e1'='e2.
ЗП1   e1=   

 

 

 

 

 

 

 

 

 

 

 

 


вверх

FIRST - выделение первых n термов


FIRST sne1=k/FIRST1//0/sn()e1.
FIRST1 snsne1=e1
       sisn(e1)='*'e1
       sisn(e1)w2e3=k/FIRST1/k/P1/si.sn(e1w2)e3.

Приведенная функция FIRST берет в скобки первые sn (количество, указанное первым символом) термов области конкретизации. Если столько термов не нашлось, - возвращает первым символом звездочку ('*').

Ещё одно решение (без вспомогательной функции):
FIRST (snsne1)e2=(e1)e2
      (si  e1)w2e3=k/FIRST/(k/P1/si.  e1w2)e3.
      sne1=k/FIRST/(/0/sn)e1.
      (sisne1)='*'e1

1-е предложение (строка) - завершение работы, когда отобрано sn термов;
2-е - "рабочий цикл", т.е. увеличение счетчика и отбор терма;
3-e - инициализация работы функции;
4-е - завершение работы, когда оказалось меньше sn термов.

Порядок предложений выбран для увеличения эффективности: проверять, что отобрано sn термов (1-е) каждый раз надо до "рабочего цикла" (2-е), инициализация (3-е) случается всего 1 раз, а выход до достижения sn (4-е) - только иногда.

Аналогично, LAST - выделение последних n термов:

LAST sne1=k/LAST1//0/sne1().
LAST1 snsne1=e1
       sisn(e1)=e1'*'
       sisne3w2(e1)=k/LAST1/k/P1/si.sne3(w2e1).

 

 

 

 

 

 

 

 

 

 

 

 


вверх

CVBN - перевод значения в строке в макроцифру


CVBN (s1e2)sm=k/CVBN/(e2)k/ADDN/k/MULN/sm/10/.k/SUBN/s1'0'...
     ()sm=sm
     e('0123456789')1=k/CVBN/(e1)/0/.
3-e предложение (строка) - инициализация работы функции (заодно проверяет что получены цифры);
2-е - завершение работы, когда все цифры обработаны;
1-е - "рабочий цикл", умножаем накапливаемое значение на 10 и прибавляем левую цифру.
Порядок предложений выбран для увеличения эффективности: 2-е и 3-е предложения срабатывают по одному разу за вызов.

 

 

 

 

 

 

 

 

 

 

 

 


вверх

hex - перевод строки символов (объектных знаков) в 16-ричное представление


hex s1e2=k/hex1/k/DRN/s1/16/..k/hex/e2.
    =
hex1 s1s2=k/hex1/s1.k/hex1/s2.
     s1=k/hex1/k/FIRST/k/P1/s1.'0123456789ABCDEF'..
     (e1sz)e2=sz

 

 

 

 

 

 

 

 

 

 

 

 


вверх

cmp - сравнение строк


cmp (s1e2)s1e4=k/cmp/(e2)e4.
    (s1e2)s3e4=k/CMPN/s1s3.
    ()='='
    w1='>'
    e2='<'
Лексикографическое сравнение по кодам символов. При первом неодинаковом символе вызывается встроенная фуннкция CMPN (см. Встроенные рефал-функции (машинные процедуры)).
1-я строка заключается в скобки, вторая - нет.
Возвращается только результат сравнения ("<", "=" или ">").

 

 

 

 

 

 

 

 

 

 

 

 


вверх

sort - сортировка строк


sort e1=k/sort2/k/sort1/k/sort0/e1...
sort0 w1e2=(w1)k/sort0/e2.
      =
sort1 w1w2ee=(k/sortt/w1w2.)k/sort1/ee.
      w1=w1
      =
sortt (w1e2)(w3e4)=k/sortt/k/sortc/w1w3.(e2)(e4).
      (e2)(e4)=e2e4
      ('>'e0)w1w3(e2)(e4)=w3k/sortt/(w1e2)(e4).
      (sce0)w1w3(e2)(e4)=w1k/sortt/(e2)(w3e4).
*sortc (s1s2s3e4)(s5s6s7e8)=(k/cmp/(s1s2s3)s5s6s7.)(s1s2s3e4)(s5s6s7e8)
sortc w1(e2)=(k/cmp/w1e2.)w1(e2)
sort2 (e1)=e1
      =
      e2=k/sort2/k/sort1/e2..
Лексикографическая сортировка строк по кодам символов методом последовательных слияний. Используется функция сравнения строк cmp.
Функция sort0 каждую строку преобразует в "группу строк", состоящую из одного эдемента.

Это - внутренняя сортировка строк, обрабатываемых программой на рефале. Для сортировки файла можно использовать программу sisort.exe.

При необходимости осуществлять сортировку не по всей строке, а только по первым трем символам (метка поля в форматах на основе ISO-2709) - следует закомментированную строку с функцией sortc раскомментировать, а следующую строку с этим же именем функции - закомментировать. При этом поля формата (usmarc или unimarc(rusmarc)) встанут в нужном порядке, а порядок полей в группах с одинаковой меткой не изменится.