Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |
указанную. Потому как преобразовывать приходится исключительно русские буквы:
латинские во всех кодировках — одна и та же ASCII... Это чтобы небыло
путанницы. А латинские соответственно зарезервируем под другие встроенные
преобразования, буде они когда появятся...
Выбор самих буковок... В основном очевиден: 866 досовская — 'Д'; 1251
виндовая — 'В' ('W'конешно смотрится лучше...); КОИ-8 — 'К'; уникод — 'У';
Исо-8859.5 — 'И'; тоже досовская 855 для братьев-славян — 'С'; ебздиковская
производная ДКОИ — 'Е'... А для кучи национальных вариантов никаких букв не
напасешся — так и придётся выдавать их во временное пользование. (Так же как в
операторе Опер мы буковки вновь открытым файлам "сдаём в аренду".) То есть
придумать, как описывать если не кодировку целиком, то хотя бы отличия такого
варианта от одного из базовых. Или хотя бы загружать заранее заготовленное.
(А то у нас оператор Load так до сих пор никак и не...) Но потом.
Ой, а про "полукорреляцию" то совсем забыли!
Чуть выше я сказал, что мол других встроенных операций (не перекодировок)
на настоящий момент пока больше не придумано... Оказывается, это не совсем так.
В отличии от поиска, операция '%п' (вернее 'п'-латинское — ну ведь
договаривались же!) ищет не весь указанный ей в качестве аргумента фрагмент
целиком, а только одинаковые слова — самый большой совпадающий кусок. И не во
всей строке, а только в её части, выделенной маркером. А просто 'п', которой
аргумента не положено — "автокорреляционная функция" указанного ей фрагмента с
самим собою. Но центральный её максимум — игнорирует. (Разумеется, сам с собою
фрагмент заведомо совпадает, но это неинтересно.) Если буква заглавная — то
критерии более строгий: игнорируются так же наложения частей одного слова. То
есть в "мамамама" 'p' найдёт слово "мамама" а 'P' — нет. (А слово "мама" — да.)
А вот название досталось по-наследству от проекта Фокал-3. Там
предполагалось пойти обычным путём полиморфизма: ввести еще один тип данных
"строка". (Даже два: еще и "пустое" значение, любая операция с которым вызывает
ошибку. Оно содержится в переменной, которой еще ничего не присвоили.) Хранить
значения всех этих типов в одних и тех же переменных, обрабатывать одними и
теми же операциями... Проект возник, когда придумалось как доопределить для
строк имеющиеся в Фокале пять операций: ну то, что строка+строка это их
сцепление ("конкатенация") — тривиально; что умножение и деление строки на
число это её размножение (повторение указанное количество раз) и разрезание на
части — не трудно догадаться буквально в течении пяти минут. А потом еще минут
за десять додумать конкретику: что будет если числовой операнд нецелый, меньше
единицы и вообще отрицательный? (Отрицательный для умножения — реверс. Он же
для операции унарный минус. А для деления — отчитываем символы не с начала
строки а с конца.) Главное: что бы могла значить операция вычитания двух строк?
Конструкция оператора If такова, что числа приходится сравнивать вот как
раз путём вычитания. Ну так пусть и строчки — тоже: пусть операция бинарный
минус ищет с какой позиции одна строка входит в другую как подстрока. (Если
первая строка входит во вторую — результат будет отрицательный, а если ни одна
не является частью другой — то ноль.) Интересно, что при вычитании строки из
самой себя получится 1, а числа — ноль. Ну значит и вычитание из самого себя
пустого значения должно давать -1. Нам же надо, например, определить тип
аргумента, переданного в функцию. А ведь данный аргумент может быть и пропущен.
Это сейчас у нас локальная переменная под него просто не создаётся...
Ну а дальше всё просто: унарный плюс пусть даёт размер строки — заведомо
числовое значение; умножение и деление одной строки на другую (а не на число)
тоже что-то такое-этакое. Например замена символов и сопоставление с шаблоном.
Для чего второй аргумент должен быть строкой специального вида. (При чем для
умножения — это последовательность пар шаблонов: анализирующего и
генерирующего. А генерирующие шаблоны реализованы вот только сейчас, и то пока
что в первом приближении.) А вот к чему приткнуть возведение в степень?
Вот операции ^ и было решено поручить поиск одинаковых общих подстрок.
Вернее первой самой большой. А чтобы эту операцию можно было применять и для
"автокореляции" (с некоторыми предосторожностями: отрезав от левого операнда
первый символ) сдвиг второго операнда относительно первого — только вправо.
Соответственно полная корреляция: FMAX(x^y, y^x)... Вот это название операции
'П' и досталось...
А то оказывается, что с "хирургическими" методами у нас полный ажур, а вот с
"постановкой диагноза"... Такую простую вещь как нахождение в двух строках
одинакового фрагмента (но заранее неизвестного) придётся делать пещерными
методами — таская по одному символу с помощью FCHR...
Ну а с 'Б', 'б', 'Р', 'р', 'Л', 'л' как со средством преобразования всех
букв в заглавные, строчные, русские и латинские я решил малость повременить:
с учетом 'о' и 'О' — подумать надо... Да и с шаблонами как-то согласовать.
* * *
(4.6) Вот, кстати, как раз про эти самые шаблоны...
Обратим внимание, что при всём кажущемся обилии конструкций форматного
выражения, основных операций — по пальцам пересчитать:
— две для перемещения маркера
— собственно перемещение на N символов — указывается числом
— поиск (сопоставление с содержимым А2) — указывается строкой
— две для изменения содержимого А2 — вставка и удаление: * /
— для / число — правый операнд, указывающий сколько удалить
— для * строка — правый операнд, указывающий что вставить
— еще одна для принудительной установки размера маркера: ~ (тильда)
— для ~ число — правый операнд, указывающий сколько установить
— и еще две константы ^ и $ для установки маркера в начало и в конец.
Все остальные — вспомогательные: либо поставляющие нам вот этот вот правый
операнд — числовой или строчный, либо выполняющие "административные" функции
как @ ( ) & ? . ! % либо указывающие направление + -
Правда в группу констант, "помогающих" ~ (тильде) устанавливать размер
маркера, тихой сапой пролезла еще и . (точка), ни с того ни с сего взявшаяся
изображать еще и "метку"... Но в целом: вот это — всё.
Строка здесь участвует всего в двух действиях: поиск и вставка. Но поиск
совершенно тупой — путём сравнения на равенство, а вставка... Ну константа-же!
Пусть даже и взятая откуда-то. Никакого анализа. И синтеза...
А вот есть у нас еще один вид как-бы кавычек — "ёлочки" <> — сам бог велел
учинить с их помощью что-то такое-эдакое: тоже текстовую константу, но
специального вида. Отличающуюся от той, которая заключается в кавычки-"лапки"
(где каждый символ изображает сам себя) тем что здесь некоторые будут иметь
специальный смысл. И первый из них как всегда главный баламут всея Фокала %
теперь в роли экранирующего символа: отбирающего этот самый специальный смысл
у других специальных символов (включая самого себя) но придающий его некоторым
из "обычных". А на роль "специальных" сразу же взялись претендовать абсолютно
все, кто не буква и не цифра. Ну может быть за исключением кавычек-лапок...
(Дело-то типа уже в кавычках происходит, где им специального смысла не
полагается.) Но и то того гляди передумают...
Да, речь идёт про "шаблон", он же "регулярное выражение". Простейшее из
которых испокон веку используется операционными системами при поиске файлов:
символ '?' которого в имени файла быть не может, заменяет собою один реальный
символ, а '*' — любое их количество: от нуля и более. Впрочем, в Дос`е и винде
шаблон этот совершенно идиотский. (Лично для тупого Билла писаный, которого
папа с мамой деньги сторожить посадили?) Ну текстовый файл на букву А найти
еще можно: "А*.txt" а попробуйте найти такой, где эта буква была бы в середине
имени: "*А*.txt", или даже "?*А*.txt" — чтобы уж точно не в начале?
Не тут то было!
Правильный шаблон только в UNIX`е. (Люди не для тупого начальства и не на
продажу — для себя писали!)
Да, алгоритм сопоставления с шаблоном — дорогостоящий, типа перебор с
возвратами. Когда (если он "жадный") первая звёздочка сперва захапает себе все
символы. Глядь, а остаток шаблона ("А*.txt") не сопоставляется! Приходится
отдавать. Но поштучно. И каждый раз заново пробует — ну может вот сейчас уже?
А следующий метасимвол делает то же самое... Если алгоритм "ленивый" — всё
наоборот: каждый метасимвол пытается спихнуть всю работу на следующих.
И только если ничего не получается...
Вот наш шаблон — это немножко улучшенный вариант UNIX`овского. Отличающийся
тем, что во-первых в нём есть еще и "встроенные" шаблоны вида: %Буква (например
%Ц — любая цифра, а вот %Б — не любая буква, а только заглавная). А во-вторых
? и * не сами по-себе заменяют один или несколько символов, как в шаблонах
файловых систем, а действуют на следующую после них конструкцию, предписывая
повторить её 0-1 и 0-много раз. То есть превращаются в "префиксы повторения".
(Вместо * теперь *. где точка вот как раз и изображает собою любой символ.)
И этих префиксов повторения — больше: '+' означает 1-много, {N} — ровно N раз,
а {N,M} — не менее чем N но и не более чем M. (При чем N и M — фокаловские
выражения.) При их пропуске — ноль и много (типа бесконечность).
Так что: '*' эквивалентна {,} '+' — {1,} a '?' — {,1}
((Впрочем, вряд ли я открыл Америку: вроде бы и в других языках, где есть "регулярные выражения" тоже так сделано? Ну хотя бы потому, что ничего сильно другого и не придумаешь...))
В UNIX`овском шаблоне, кстати, есть еще и конструкция [...] заменяющая
собою тоже один символ, но не любой, а один из перечисленных внутри этих
скобок. При чем если коды символов идут подряд (как буквы или цифры) то можно
не перечислять их, а указать "диапазон": [А-Я]. А если нужен символ '-' то
велено указывать его первым или последним. Потому что порядок перечисления -
несущественен. (Не то, что у нас...)
Но диапазон — для людей хорошо представляющих, как у них кодировка устроена.
Впрочем, для пиндосов, использующих ASCII, и представлять особо нечего:
латинские буквы — строго подряд в алфавитном порядке. Правда маленькие
отдельно, большие тоже отдельно. Дополнительных букв нету. Цифры — тоже подряд.
А остальные символы и перечислить можно. Всем остальным сложнее: мало того,
что у них есть дополнительные буквы, которые невесть как расположены, так еще
и с основными бывает такая чехарда!...
У нас например буква Ё — дополнительная. В КОИ-8 её вообще нет. Вернее есть
только в совсем полном варианте (где и псевдографика предусмотрена), которого
на моей памяти нигде и никогда небыло реализовано. Ну так там и русские буквы
— в порядке чужого алфавита. При чем первой стоит буква Ю, такая же круглая,
как "Абезьяна" (она же "сАбака") @ на которую она приходится, Ш и Щ приходятся
на скобочки — квадратные или фигурные, буква Э между ними, а последним стоит
твёрдый знак! При чем заглавный — самым последним. И им частенько приходится
жертвовать: этот код, состоящий из всех единиц, очень часто применяется для
специальных целей... Так что "все" русские буквы в КОИ-8 выглядят как [ю-ъЮ-Ч]
ну или может [ю-ъЮ-ЧёЁ], или даже [ю-ЧёЁ].
В виндовой 1251 всё вроде бы тип-топ: русские буквы в правильном алфавитном
порядке. (Всё как мы любим!) Буква Ё — есть, хотя и дополнительная (ничего не
поделаешь: букв у нас 33, а 2^5 это 32 — только 32 буквы в один ряд убираются).
Ан — буква 'Я' приходится на тот самый код, который для специальных целей. А
ведь это не 'Ъ' (с которого слова никогда не начинаются) — ею не пожертвуешь!
Ну и какой вредитель/недоумок-либераст-дерьмократ это придумал?!
Да, с тех пор прошло более тридцати (!) лет и за это время большой кровью,
(разные аспекты жизни зеркально отражают друг дружку!) затратив невесть
сколько усилий, таки удалось "перевоспитать" большую часть программного
обеспечения... Полагаю, что это была не ошибка а таки диверсия. Потому что
например в более ранней ДОС`овской 866 кодировке с этим всё в порядке. Там
другая проблема (хотя и куда более мелкая): маленькие русские буквы — разрывные.
Типа: [А-Яа-пр-яЁё]. Связано это тоже можно сказать со своего рода диверсией:
псевдографика размещена по-идиотски, а передвинуть её на другое место
невозможно — зафиксирована аппаратно! То есть только в этом месте знакогенератор
не рисует промежутков между буковками...
А вот братьям-славянам с их 855 кодировкой — совсем кисло: там буквы
раскиданы как попало. При чем в основном парами: заглавная-строчная, но не все.
Впрочем нативная американская с неприличным названием и производные от неё
(наша ДКОИ например) — ничуть не лучше и вполне это неприличное название
оправдывают: надо же было учинить такое непотребство!...
Наши собственные, о которых уже мало кто помнит, были продуманы куда лучше.
Например уже упоминавшаяся безымянная "ГОСТ`овская" (известная так же как
"УПП" — от слов "устройство подготовки перфокарт") заточенная под пробивание
дырочек в этих самых перфокартах, была принципиально семибитная: восьмой бит
всегда дополнение до нечетности. "Четными" могли быть только два кода: все
нули и все единицы — место где на перфокарте еще ничего не пробито и где был
"забит" ошибочный символ. Но она была организована так, что могла быть
использована и в шести— и в пяти— и даже в четырёх-битном варианте! Да, буквы
— только заглавные. При чем по "типографскому" принципу: латинские только те,
которые не совпадают по написанию с русскими. (И это — не недостаток: вот
именно так оно всегда и должно быть!) В шестибитном варианте (а у многих машин
размер слова тогда был кратен шести: так для арифметики лучше) там были только
русские буквы. В пятибитном букв уже небыло но были все знаки математических
операций — всё что нужно для калькулятора. И даже в четрёхбитном (!) там было
всё (включая пробел) для записи числовой информации.
Однако, в семье — не без урода. И вот такой урод нашелся и подгадил: в
кодировке отсутствует вопросительный знак! Нет, люди потом как-то
приспособились, благо свободных кодов там более чем достаточно... Однако,
случай вопиющий и требует расследования. По некоторым сведениям, эта кодировка
была привязана к некоторому АЦПУ-128 (алфавитно-цифровому печатающему
устройству, возможно "барабанного" типа), а оно в свою очередь делалось под
Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |