Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |
4.5.2 Основных операций — всего две: это * вставка (замена) и / удаление. Вставке нужен строчный операнд (что вставить), а удалению — числовой (сколько удалить). Без него / удаляет фрагмент под маркером. А с префиксами — и + то что до маркера и после. Вставка с префиксами — и + вставляет соответственно не вместо указанного маркером фрагмента строки, а перед и после.
4.5.3 "Число" (как в качестве чьего либо правого операнда, так и самостоятельной операции сдвига маркера) может быть не только числовой константой в виде последовательности циферок, но и целой частью значения из фокаловской переменной со специфическим именем #X (где X — любой символ, допустимый в имени переменной и потому считающийся буквой).
Кроме того это может быть целая часть значения полноценного фокаловского выражения, заключенного в фигурные скобки. Причем там, в этих скобках, допустима так же конструкция =Х присваивающая вычисленное фокаловской переменной с именем #Х.
Сама конструкция =Х (вне фигурных скобок) присваивает переменной #Х размер фрагмента под маркером. А с префиксами — и + соответственно до маркера и после него — до конца строки.
4.5.4 "Строкой" (как в качестве чьего-то правого операнда, так и операции поиска) тоже может быть не только константа "...", но и значение переменной со специфическим именем #N (где N — цифра 0..9). Вернее "переменной" — это на будущее, а пока что — "регистра". Впрочем при записи в регистр операцией =N в переменную со специфическим именем #N автоматически кладется длина сохраняемого в регистре фрагмента: =N помещает в регистр фрагмент под маркером, а с префиксами — и + части строки до и после маркера.
Аналогично числу, строка тоже может быть сформирована с помощью фокаловского выражения, заключенного в фигурные скобки. Но увы — ничего сложнее строчной константы "..." (или ! обозначающего конец строки) первый Фокал предоставить не способен. (Это для третьего Фокала придумано, как доопределить арифметические операции + — * / и ^ для работы со строками...) Но и это имеет смысл: указать конец строки ! ВНУТРИ "..." (как Си: n) Фокал не позволяет (там это будет обычный восклицательный знак). Так что конструкция {...} даёт возможность объединить несколько "..." в одну строку. Включив туда так же и символы указанные их кодами (в виде числовых констант или фокаловских выражений). Но чтобы отличить строку от числа, надо чтобы первым в {...} было что ни будь специфически строчное, например текстовая константа, пусть даже и пустая.
4.5.5 А еще у нас есть программные строки, в которых (см. 5.4.10) позволительно хранить всё что нам вздумается (если не пытаться ЭТО выполнить: "хоть горшком назови, только в печь не ставь!"). Но у них уж больно сложные наименования — в виде дробного числа. Однако поскольку в {...} можно написать полноценное числовое выражение, то осталось придумать как отличить номер программной строки от кода символа.
Для этого в обиход вводится символ : двоеточие. Слово для его обозначения есть с русском языке хорошее — опричь (что значит "другой"). Во времена Ивана Грозного "опричниной" (в противоположность "земщине") называлась территория, где был введен другой, новый способ комплектования армии (используемый, кстати, и по ныне). А "опричниками" (не имевшими с вышеупомянутой "опричниной" ничего общего) называлась избранная тысяча личной охраны (то, что потом называлось гвардией), в которой, в отличии от других армейских соединений, было запрещено местничество и куда, кстати, царь приглашал бояр лично, и лично назначал на должности. (А уж понаписали то потом про всё это... Только идиот поверит. Однако же верят, что показывает, какие же эти люди — идиоты, не способные к критическому мышлению. Или, если таки способны — злонамеренные сволочи.)
Ну так вот: в {...} просто выражение ХХХ будет как и раньше обозначать символ с кодом, равным его целой части, а :ХХХ — программную строку с соответствующим номером.
5.4.11 По введении в обиход символа "опричь", дадим оператору Modify доступ и до вышеупомянутых регистров форматного механизма. Указывая их :N (где N — одна цифра 0..9).
5.3.0.1 Введем так же возможность использовать содержимое регистров форматного механизма везде, где допустима текстовая константа, добавив к "..." и ! еще и :N (где N — одна цифра 0..9).
Но это — кроме операторов ввода/вывода, где ! испокон веку указывал конец строки. Там : теперь будет указывать "табуляцию": переход к следующей позиции табулостопа. Были вишь в пишущих машинках такие выдвигающиеся железочки: при нажатии на кнопку ТАБ каретка ехала до следующей выдвинутой. Что очень помогало машинисткам печатать всякие таблицы. В дисплеях сделали позицией табулостопа тупо каждую восьмую. А у нас в Фокале, помнится, тоже был где-то специальный механизм для установки этих табулостопов где вздумается. Только он без дела ржавеет... Ну так пусть пользу приносит! (Чем мы хуже кота Матроскина?)
4.5.6 Конструкция #{...} где внутри фигурных скобок опять фокаловское выражение, преобразует его значение в текстовую строку — как это делает оператор Type. И в результате тоже получается "строка", пригодная к использованию как для вставки операцией * так и самостоятельно — в качестве операции поиска.
Формат для преобразования берётся тот же самый, что и в операторе Type. Но можно указать свой — после % по правилам Си-шной функции printf(), которая на самом деле это преобразование и производит. А ежели в нём указаны звездочки, обозначающие поля переменной величины, то через запятые после оного формата должно быть подобающее количество выражений, чтобы эти конкретные значения вычислить.
Парная к #{...} конструкция ={...} производит обратное форматное преобразование (с помощью Си-шной функции scanf() разумеется). Длина преобразованного фрагмента попадает в числовой аккумулятор. И после ={x} сдвинуть маркер за пределы: ={x}{fsbr()} или, например, удалить это: ={x}~{fsbr()}/
4.5.7 Операция может кончиться неуспешно. (Например подходящий фрагмент не найден. Или сделана попытка передвинуть маркер дальше конца строки.) Тогда отработка формата сразу и завершается. Но это если после операции нет "постусловия".
Постусловий два: в случае успешности & и соответственно неуспешности выполнения операции, они запускают после неё еще одну. А иначе пропускают её. Если одной операции мало — можно несколько штук заключить в круглые скобки. Третье постусловие ?...:....|, предусматривающее сразу оба случая, само себе скобки.
4.5.8 Образцово-показательная операция _ успешно выполняется всегда. Потому что ничего не делает. И вообще предназначена на роль пробела, который в форматной строке употреблять нельзя (ибо разделитель) — на нём формат сразу и закончится.
4.5.9 Если мы напишем что-то типа "вася"*"Василий" то эта конструкция найдёт и заменит только одно слово "вася" (если в обрабатываемой строке оно вообще есть). А если нам надо все, а в строке их может быть несколько, то нам понадобится префикс повторения: @("вася"*"Василий") который циклически выполняет одну, следующую после него операцию. Как всегда до первой ошибки. Но только одну — поэтому и пришлось использовать круглые скобки. (Здесь операций две: поиск и замена найденного.)
Префиксу повторения можно так же указать число повторений — в виде числовой константы, значения переменной #Х или выражения в фигурных скобках. Если в них встречается =Х, то переменная #Х станет параметром цикла. (Или последняя из них, если несколько.) И будет изменяться от количества повторений до нуля. Но если =Х в @{...} есть, а выражения нету — цикл таки будет без ограничения количества итераций, а переменная #Х станет их счетчиком — будет изменяться "в плюс". Впрочем, значение счетчика повторений цикла доступно и так — через числовой аккумулятор.
В конструкции @{...}, в отличии от просто {...}, может быть несколько выражений — через запятую. Тогда первое становится начальным значением, второе конечным, а третье — шагом. В точности как в операторе For.
Но заголовок цикла @{...} может быть и "строчного" типа. Тогда его содержимое сопоставляются с обрабатываемой строкой, начиная от маркера. И если не сопоставилось — цикл завершается. (А размер сопоставившейся части тоже попадает в числовой аккумулятор.)
Кроме обычных текстовых констант "..." и восклицательного знака, обозначающего символ, разделяющий строки (с кодом 10, в на языке Си его еще пишут как 'n') а так же обращений к регистрам #N и "программным" строкам :NN (где NN — фокаловское выражение), ну и чисел, обозначающих коды символов (тоже фокаловские выражения, но без предшествующего двоеточия, которое, кстати, если в одиночку, то обозначает 't' — код табуляции), там еще допускаются ^ и $ обозначающие начало и конец строки. (Не путать с ! — символом 'n'.)
Сюда так и просятся конструкции (что ни будь типа %Б, %Ц...) обозначающие любую букву и цифру, любой символ из перечисленных (что ни будь типа [...]) и префиксы повторения (типа * + ?) — как в "регулярных выражениях" (они же "шаблоны"). Но пока чего нет того нет.
4.5.10 Если сразу же после префикса повторения идёт постусловие, а операция, которая должна бы выполняться в цикле — отсутствует, то получается условное выражение. (Вот выполнился бы цикл хоть один раз — значит условие "истинное".) В принципе условным выражением можно считать любую операцию и постусловие после неё, но там "условием" является успешность её выполнения, что несколько другое.
Кстати, тот же самый цикл выполнен "успешно" если завершился по исчерпании количества повторений. А если по ошибке, то нет. И к самим постусловиям & и это тоже относится, вернее к операции в них. Пропускают то они её всегда успешно.
* * *
Пусть нам надо что-то вычислить и в переменной сохранить; или что-то такое сделать, вызвав фокаловскую подпрограмму (ф-ей FSUBr разумеется), но чтобы при этом ничего в обрабатываемой строке не попортить. Запросто: пишем вот такое условное выражение с образцово-показательной ничего не делающей операцией _ и всё: @{.....}&_
4.5.11 Операцией ! можно немедленно завершить отработку формата. Попутно запретив вывод. Впрочем, перед этим операцией . (точка) можно учинить его принудительно.
Префиксы на две эти операции тоже очень даже действуют: -! позволяет вообще завершить работу оператора Write, а +! еще и завершить "со скандалом" — с ошибкой 3.6 (или какой указано с помощью числового аргумента).
Для . префиксы напротив предписывают вести себя более скромно: +. выдаёт в канал вывода не всю строку в аккумуляторе, а только ту её часть что после маркера. ("Еще не использованную". Mы не забыли, что маркер, это одновременно и указатель места, до которого строка в буфере уже якобы использована предыдущими операторами Ask?) А -. вообще только то что под маркером.
* * *
Вот например надо "промотать" часть текстового файла, чтобы добраться до... Ну это мы таки взялись писать упоминавшийся в 4.3 скриптовый файл, и нам надо передать управление вперёд. Если бы назад — не было бы проблем: запомнили бы файловый адрес в переменной, а сейчас позиционировали бы туда оператором О. Но и вперёд — не проблема: в предшествующей нужному для нас месту строке напишем некую "метку" и прочитаем все строки до неё оператором W % "метка";. Вот только куда всё это девать? Оператор Write не просто читает, а копирует!
А вот: в операционной системе есть такое полезное устройство nul, где бесследно исчезает любая записанная туда информация. Вот можно туда. Но можно проще: W %! "метка"; и всё — теперь он их только читает и никуда не пишет.
Или еще проще: надо подсчитать количество строк в файле. Для чего промотать его до конца. Но это же ошибка "конец файла" будет! Да, конешно — можно поставить ловушку... Но укажем в качестве количества строк -1 и ошибки не будет: O (0) f; O fr; W %! -1; O k; T FSBr(),"строк";. А количество скопированных оператором строк взяли из числового аккумулятора (упоминавшегося в 5.3.4 и далее).
* * *
А вот с выделением фрагмента у нас дела обстоят как-то хило: фрагмент можно найти (операцией поиска) или установить некоторого размера, указанного числовым параметром. И всё.
4.5.12 За сим на помощь маркеру решено было призвать "метку". Ввести операцию "установить" =. её там, где сейчас маркер и "применить" #. в результате чего метка и маркер меняются местами. (Длина маркера при этом становится равной нулю. Коль надо её сохранить — запомним в переменной: =x#.~#x )
А так же ~. установить размер фрагмента между меткой и маркером (ну или с префиксами — добавить к). И за одно установить до начала ~^ и до конца ~$ строки.
Нет, запомнить положение маркера можно было и раньше — в переменной: -=x и установить размер фрагмента от запомненного места до текущего — тоже. Вот примерно вот так: -=y^{fmin(x,y)}~{fabs(x-y)} — но уж больно это громоздко...
4.5.13 Конструкции %N производит применение содержимого регистра N в качестве форматного выражения, что эквивалентно вызову подпрограммы. А %{:NN} или %{NN} использует для этого одну из программных строк.
Но кое что здесь определенно недодумано. Поэтому на всякий пожарный после такой конструкции лучше бы добавить пустую операцию _ (а то есть мысль сделать передачу в такую "подпрограмму" аргумента...)
### фокаловское выражение в фигурных скобках может содержать в себе в том числе обращение к спецфункции FSUbr — фактически вызов фокаловской подпрограммы, где может быть что угодно. В том числе и оператор Write %.., что вполне допустимо. Но надо иметь в виду, что строчный аккумулятор — один на всех. И прилагающиеся к нему "регистры" — тоже. А ведёт W % себя... Ну не то что бы по свински, но буфер после себя оставляет пустым. (Если на "метку" не наткнулся.) Однако, если велеть ему скопировать ровно ноль строк: W %... 0 то ничего — только обрабатывает что в буфере и ничего не портит.
4.5.14 Итак: круглые скобки (...) объединяют несколько операций в одну; угловые <...> заключают в себе "шаблон", фигурные {...} — фокаловское выражение, а квадратные [...] пока не задействованы — зарезервированы под что-то, не дающее числового результата. (При нижеследующем формальном описании грамматики они обозначают необязательность; а символ | разделяет варианты.)
А вот кавычки (коих три: " ' `) у нас все эквивалентны, но опять же не взаимозаменяемы — их самих можно заключить в кавычки другого типа. (Деваться некуда: все три непарные.)
Основных операций всего две: *[строка] и /[число] — вставить и удалить.
Операций поиска тоже две: строка и шаблон
Операций сдвига маркера три: число ^ $ и в дополнение к ним #. + —
Операция установки ширины маркера всего одна: ~[число | ^ | $ | .]
Операций с меткой три: =. #. ~. установить и применить к
Установить и применить: =Y #Y применимы так-же к "регистрам" (Y=0..9), переменным (Y — буква), а если Y это {...} то получаются преобразования меж строкой и числом по указанному в фигурных скобках Си-шному формату. Причем "установить" не на что особо не влияет (кроме того, что устанавливается), а "применить" даёт либо число либо строку.
Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |