М. В. Ломоносова Факультет вычислительной математики и кибернетики Е. И. Большакова, Н. В. Груздева Основы программирования на языке Рефал Учебное пособие
Скачать 0.92 Mb.
|
2.2.Переменные и их спецификацииПеременная языка Рефал-2 имеет вид: признак_типа [спецификация] индекс Индекс переменной – это цифра или буква русского или латинского алфавита. Спецификация может отсутствовать. Признаком типа служат следующие буквы: s и S, w и W, e и E, v и V (соответствующие буквы верхнего и нижнего регистра являются эквивалентными). Например, S‑переменные: S1, S2 и sA; W-переменные: W1 и Wх; V‑переменные: v9 и VZ; E-переменные: E1, e5 и EA. Во всех этих переменных спецификация пуста. При записи переменных пробелы между признаком типа и спецификацией, а также спецификацией и индексом недопустимы. По типу значения переменные разбиваются на: S-переменные, значением которых может быть только символ-литера, символ-метка или символ-число; W-переменные, значением которых может быть только символ или структурный терм; E-переменные, значением которых может быть произвольное объектное выражение (в том числе и пустое). V-переменные, значением которых может быть только непустое объектное выражение; К примеру, для S-переменной в качестве значения допустимы следующие символьные выражения: 'G', '+', /172/, /alpha-beta/. В то же время её значением не могут быть выражения '172', '-'/172/, ('a+b'), поскольку первые два выражения представляют собой цепочки соответственно из трёх и двух символов, а третье выражение – структурный терм. В качестве значения W‑переменной допустимы, например, выражения 'G', '+', /172/, /alpha/, ('a+b'), но недопустимы выражения '172', '-'/172/, 'Х'('a+b'), поскольку первые два есть цепочки символов, а третье состоит из двух термов. V- и E-переменные, называемые также переменными типа выражение, могут иметь в качестве значения произвольное объектное выражение, однако пустое выражение допустимо в качестве значения только для E-переменных. Заметим, что пустое выражение не может быть значением и W‑переменной. Спецификация переменной в языке Рефал-2 представляет собой мощное выразительное средство, позволяющее гибко ограничивать множество объектных выражений, которые могут быть значениями переменной. Спецификация бывает двух видов – либо непосредственное задание ограничений на значения переменной, либо указание имени спецификатора, определяющего множество допустимых значений: спецификация ::= (набор_ограничений) | спецификатор Рассмотрим сначала первый вид спецификации. Набор ограничений состоит из элементов спецификации, каждый из которых задаёт допустимые объектные выражения. Элементом спецификации может быть конкретный символ, например: 'к', /21/, /beta/, стандартное множество однотипных символов или термов, или же множество, задаваемое спецификатором. Соответствующие БНФ‑правила: элемент_спецификации ::= символ-литера | символ-число | символ-метка | стандартное_множество | спецификатор стандартное_множество ::= S | F | N | O | L | D | W | B Как стандартные зафиксированы следующие множества: S – множество всех символов; F – множество символов-меток; N – множество символов-чисел; O – множество символов-литер (объектных знаков); L – множество букв (русских и латинских); D – множество десятичных цифр; W – множество всех термов; B – множество структурных термов, т.е. термов вида (R), где R – произвольное объектное выражение Рефала. Из элементов спецификации может быть составлена цепочка, которая обозначает объединение соответствующих множеств допустимых значений: цепочка_элементов_спецификации ::= пусто | элемент_спецификации цепочка_элементов_спецификации Например, цепочка L'5' задаёт в качестве допустимых значений все буквы и цифру 5, а цепочка LD – все буквы и цифры. Если в цепочке элементов спецификации содержится несколько символов-литер подряд, их можно слить в одну цепочку литер. К примеру, цепочка '+-*/' описывает множество знаков арифметических операций, а цепочка D'ABCDEFabcdef' обозначает множество из цифр и латинских букв A, B, C, D, E, F, a, b, c, d, e, f, т.е. представляет все шестнадцатеричные цифры. Набор ограничений строится из цепочек элементов спецификации следующим образом: набор_ограничений ::= цепочка_элементов_спецификации | цепочка_элементов_спецификации (цепочка_элементов_спецификации) набор_ограничений В общем случае набор имеет вид Cn+ (Cn-) Cn-1+(Cn-1-) … C1+(C1-) C0 , n0 , где Ci+ и Ci- – цепочки элементов спецификации, и интерпретируется следующим образом. Если n=0, то в набор ограничений входит одна цепочка C0, и именно она описывает множество допустимых значений. Если же n1, то множество допустимых значений Mnопределяется по рекуррентной формуле: Mn = Cn+ (Mn-1\Cn-) где и \ – операции объединения и разности множеств, а Mn-1 – это множество, определяемое набором ограничений Cn-1+(Cn-1-) … C1+(C1-) C0. Отметим, что цепочка C0 при n1 может быть опущена – в этом случае по умолчанию считается, что C0 W (множество всех термов). Приведём примеры наборов ограничений и соответствующих допустимых значений: 'ABC' – любой из символов-литер 'A', 'B', 'C'; ('ABC') – любое выражение-терм, за исключением символов-литер 'A', 'B', 'C'; ('A')L – любая буква, за исключением буквы 'A'; ('XY')L('0')D - любая буква, за исключением букв 'X' и 'Y', или любая цифра, за исключением цифры '0'. Набор ограничений, записанный в скобках, представляет собой спецификацию переменной, и трактовка этой спецификации зависит от типа переменной. Спецификация S- или W-переменной описывает множество допустимых значений этой переменной, в то время как спецификация V- или E-переменной определяет, к какому множеству должен принадлежать каждый терм верхнего уровня выражения, являющегося значением этой переменной. Приведём примеры специфицированных переменных, указывая их возможные значения: S(('89')D)1 – восьмеричная цифра; S(D'abcdefABCDEF')2 – шестнадцатеричная цифра, причём все цифры, большие 9, могут записываться как строчной, так и прописной латинской буквой; S((/0/)N)3 – целое неотрицательное число, отличное от нуля; W(B)4 – произвольное объектное выражение в структурных скобках; V(('89')D)5 – восьмеричное число без знака; V(D'abcdefABCDEF')6 – шестнадцатеричное число без знака; V('+-')x – непустая последовательность из знаков '+' и '-'; E('+-')x – произвольная, возможно пустая, последовательность из знаков '+' и '-'; E(('+-'))X – выражение, которое не содержит на верхнем уровне ни одной литеры '+' или '-', значением переменной может быть, например, выражение ('+')('-'), но не выражение '+'('-'); E(B)x – последовательность, возможно пустая, из структурных термов, например: ('A+D-S')(/56/'+'/45/)()('A'('BC')'DE'). Две стоящие подряд переменные S(L)x E(LD)y означают идентификатор в обычном его понимании, т.е. последовательность из букв и цифр, начинающаяся с буквы. Заметим, что при записи спецификации переменной можно вставлять пробелы после открывающей ( и перед закрывающей ) скобками спецификации, а также между элементами цепочки спецификации, например: S( (/0/) N )3 эквивалентно S((/0/)N)3. Рассмотрим теперь второй вид спецификации – указание имени спецификатора, при этом слева и справа от имени записываются знаки двоеточия : спецификатор ::= :имя_спецификатора: В этом случае требуется предварительно определить этот спецификатор рефал-предложением вида имя_спецификатора S набор_ограничений Такое предложение вводит (определяет) новый спецификатор с указанным именем и связывает это имя с заданным набором ограничений. В дальнейшем это имя можно употреблять в качестве спецификации или элемента спецификации. К примеру, определив спецификаторы знаков арифметических и логических операций: ArOper S '+-*/' LogOper S 'V&' можно далее использовать их, записывая в рефал-программе переменные S:ArOper:x или S(:ArOper: :LogOper:)y. Значением переменной Sx может быть только знак арифметической операции, а значением Sy – знак арифметической или логической операции. Заметим, что поскольку элементом спецификации может быть спецификатор, спецификация вида :имя_спецификатора: равносильна спецификации (:имя_спецификатора:), поэтому переменные S:ArOper:x и S(:ArOper:)y имеют одно и то же множество допустимых значений. Именем спецификатора может быть произвольный идентификатор. Имена спецификаторов, в отличие от имён рефал-функций, не являются символами-метками. На использование имён спецификаторов наложено следующее ограничение: если имя некоторого спецификатора используется при описании другого спецификатора, то оно должно быть описано к моменту использования. Соответствующий пример показывает последовательное введение и использование спецификаторов Binary, Octal и Decimal для двоичных, восьмеричных и десятеричных цифр: Binary S '01' Octal S :Binary: '234567' Decimal S :Octal: '89' |