Страница произведения
Войти
Зарегистрироваться
Страница произведения

Руководство по Фокалу


Автор:
Жанр:
Изобретательство
Опубликован:
22.04.2025 — 23.04.2025
Читателей:
1
Аннотация:
Нет описания
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

(операции ** и //) временно....


* * *

Итак, еще раз про встроенные шаблоны вида %Х (где Х — одна буква) как

анализирующие так и генерирующие.

Договоримся, что любая конструкция вида %буква это обязательно встроенный

шаблон. Даже в том случае, если таковая буковка никак не задействована,

анализирующий просто ни с чем не сопоставится, а генерирующий ничего не

сгенерирует, проигнорировав доставшийся ему элемент протокола.

АНАЛИЗИРУЮЩИЕ встроенные шаблоны делятся на две группы: первые

сопоставляются с одним символом, вторые — с некоторой сложной конструкцией,

типа плавающее число (с мантисой и порядком), грамматически правильное

выражение, или хотя бы сбалансированная скобочная структура...

Из них пока реализован один только %S сопоставляющийся с текстом в

кавычках. Проблем — две: первая — как зафиксировать такую конструкцию в

протоколе и вторая, более сложная — в универсальности. Первая проблема

порождается спецоперациями ** и // позволяющими "вытащить" протокол на свет

божий и загрузить обратно, для чего он должен быть исключительно в текстовом

виде. Она вполне решаема. Вот только решения эти мне что-то не больно-то

нравятся. (Ну да: введением таки только и исключительно для протокола текстовой

константы с экранирующим символом.) Вторая заключается в том, что например мы

считаем "скобками" а что — нет? Мы то в Фокале их числим четыре вида: ([{<>}]),

а где ни будь в другом месте <> скобками не считаются. А еще кому-то

понадобится выделять фрагменты, заключенные в '/' и ''. Ну и что делать?

Получается, что встроенному шаблону, анализирующему скобочную структуру, надо

передавать параметры! Интересно, как? Хотя у нас вон там еще "постфикс" никак

не задействован... А еще есть проблема рекурсивности, которую надо

рассматривать отдельно: скобочки же могут вкладываться друг в дружку как

матрёшки на любую глубину... А если скобочка в кавычках, то скобкой она типа

не считается? Да и кавычки (не у нас!) во первых могут быть парные, а

во-вторых иметь в комплекте экранирующий символ...

Но отложим это (до следующей версии).

Пока что нас интересуют те встроенные шаблоны, которые сопоставляются с

одним символом, таким как буква, цифра, разделитель, символ псевдографики...

Но это анализирующий — сопоставляется. А парный к нему генерирующий должен

вставить нечто, получившееся из того, что получил от него через протокол.

Два крайних случая: символ, изображающий сам себя, себя же и генерирует,

игнорируя информацию из протокола. А шаблон . (точка), сопоставляющийся с

любым символом, и вставляет тоже что угодно. Один в один. При чем любую, сколь

угодно сложную конструкцию. Ага. А все остальные?

Перечислим их (честная ревизия кода, а не что я на этот счет думаю)

"объединение" (буква О может быть как русской так и латинской)

%о (строчная буква) — не различать заглавные и строчные буквы

%О (заглавная) — не различать русские и латинские

Инвертирует текущее состояние этого признака. (С учетом алгоритма

сопоставления, идейка, честно говоря сомнительная.) Следов в протоколе не

оставляет.

В генерирующем шаблоне (как это уже было написано выше) вставляет

конструкцию типа %о+ указывающую в каком этот признак состоянии.

"кодировки" (буквы — исключительно русские)

%Д %д — ДОСовсская 866

%В %в — виндовая 1251

%К %к — КОИ-8

%У %у — уникод

%И %и — ИСО 8859.5

%М %м — макинтош

Заглавная буква -> русские заглавные, строчная -> строчные. Латинские

буквы у всех перечисленных совпадают с латинскими текущей кодировки.

Планируется так же сделать:

%С %с — славянская 855

%Е %е — ебздиковская производная ДКОИ.

И вот у последней всё не так! Но пока не сделано, а там — подумаем...

(С учетом %О выделить можно любые буквы, а вот с прочими символами как?)

"типы букв" (в текущей кодировке)

%Б %B — любые заглавные

%б %b — любые строчные (но это если признак %о не установлен)

%Р %R — заглавные русские

%р %r — строчные русские

%Л %L — заглавные латинские

%л %l — строчные латинские (аналогично для признака %О)

другие классы символов (тоже в текущей кодировке)

%Ц %ц %C %c — любая цифра

%Г %г %G %g — любой символ псевдографики

%П %п %P %p — пробел или любой "слепой" символ с кодом меньше пробела

если русская (%П %п) — плюс то, чем может завершиться слово:

знаки препинания '.' ',' ':' ';' '!' '?' и конец строки

если строчная (%п или %p) — один такой символ,

а если заглавная (%П или %P) — все сколько их подряд

уникод

%U — аналог . (точки) — один символ текущего уникода

%V -//— — один правильный символ utf-8

%u %v — символ с кодом FEFF (неразрывный пробел нулевой ширины) по которому

обычно определяют тип уникода

Как уже говорилось ранее, уникод различаем "входной" и "выходной". В

данном случае входной — для анализирующего шаблона, а выходной — для

генерирующего. Устанавливаются операцией %О с числовым аргументом, но могут

быть установлены и с помощью вот этих вот встроенных шаблонов. При чем %u

определяет и устанавливает тип входного уникода только когда он

"неопределённый" — равен 0, а %v — всегда (т.е. переопределяет его заново).

На текущий момент (03.01.24/14:00) это всё что есть.

Вспомним, что генерирующему шаблону может быть передано через протокол?

— ноль символов: _

— одиночный символ: .x Аx Unnn, ! где: х — вот этот самый символ,

— группа символов: $/xxx/ &"xxx" А — буква, n — цифра

— выбор: [nn,Y] Y — любая из описанных

— последовательность: <...> здесь конструкций

— повторение: ...*...|... ... — их последовательность

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

Итак, что видим? Видим деление символов на ранее упоминавшиеся классы

(буквы, цифры, псевдографика...) с выделением подклассов среди букв. (Те, что

обозначены как "кодировки" — тоже буквы, при чем русские.) Вернее

соответствующий анализирующий шаблон выделяет из входного потока символ

относящийся к этому классу и соответственно генерирующий должен вставить в

выходной поток тот же самый символ, преобразовав к своему подкассу. А если

преобразование не требуется, то там вполне можно поставить шаблон . (точка).

Ага. Вопрос только в том, что ему делать, если достанется символ

относящийся к другому классу?

— преобразовать к своему классу (а это вообще возможно?)

— вставить как есть

— не вставлять ничего

Последний случай имеет смысл если есть возможность выбора. Например в виде

конструкции [...] не парной к аналогичной конструкции анализирующего... Сейчас

то в этом случае тупо используется первый её элемент. А надо, чтобы подходящий!

Впрочем, возможен компромис: за пределами вот такой вот конструкции пусть

всё "чужое" вставляет один в один (как точка), а внутри — только "своё".

За одно разрешается и еще только наклёвывающяся проблема с перекодировками:

псевдографику (если она есть) тоже нужно перекодировать, а если нету — как-то

изобразить ("транслитерировать"). При чем существуют кодировки (не

реализованная пока ДКОИ например), где не только русские но и латинские буквы

закодированы принципиально по-другому. Да и все остальные символы тоже...

А преобразование символов между классами (например букв в цифры или в

символы псевдографики) пока что не представляется мне вомзожным.

Поэтому вот так и сделаем: за пределами конструкции [...], которой пока

что еще и нет, любой встроенный "одиночный" шаблон пусть вставляет все

"не-свои" символы один в один — как . (точка). И в роли "постфикса" — тоже.

(Которого тоже пока что нет — это после двоеточия.)


* * *

В общем будем считать, что про шаблоны пока всё.

— что там у нас еще осталось?

— а вот:

(4.9) %r и %R — близнецы братья (кто более матери-истории ценен?...)

Ну даже настоящие близнецы не совсем похожи — и тут так же. Напоминаю:

в начале был реверс — перестановка в обратном порядке: битиков в байте и самих

байтиков в указанном маркером фрагменте. (А битиков — тоже в каждом байте

фрагмента, вообще-то.) Вот это они по наследству и получили: %r работает

последовательно с каждым байтом фрагмента, а %R с ним со всем как с единым

целым. Но делать умеют почти одно и то же: свои операнды они рассматривают не

как буквы, цифры и прочие знаки препинания, а как наборы битов. (Они же

беззнаковые целые числа.)

А всё потому, что никак не получалось придумать — как одновременно указать

преобразование и между заглавными и строчными буквами, и между русскими и

латинскими, и, главное — всё это еще и для других кодировок, где тоже всё это

есть... Нет, по-отдельности — пожалуйста. А вот всё вместе... Сделать-то не

проблема, а вот как указать, что имено надо делать, да еще так, чтобы и самому

не запутаться!... Отсюда и появилась идея промежуточной кодировки, такой, чтобы

там все нужные нам преобразования производились изменением буквально одного -

двух битов. Чтобы там все буквы стояли единообразно: младшие ну например шесть

бит указывали конкретную букву, а все старшие были бы её признаками: седьмой

бит — заглавная или строчная, восьмой — русская или латинская. А если битов

больше, то и на другие алфавиты можно замахнуться...

Ага, замечательно. Но с одной стороны не все буквы — буквы: меж ними и

цифры встречаются, и прочие знаки препинания. А с другой — нужен инструмент,

чтобы эти битики признаков переворачивать. (Без инструмента и вошь не

раздавишь: ноготь нужон!) И инструмент по-возможности универсальный. То есть

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

Вот и.

А если учесть, что у нас есть еще и кошкой драный уникод, который в один

байт ну никак не укладывается... В общем делаем так: берём очередную буковку

(сколько бы байт она ни занимала), тащим её в тихое место, и уже там что-то с

нею делаем. А сделав — кладём назад. Или сохраняем про запас... Где? Да хоть

в переменной, хоть одном из регистров...

Образчик этого самого "тихого места" (операционный стэк) дают нам

советские программируемые микрокалькуляторы. А так же язык Форт и/или

ПостСкрипт если кто о них знает. Но там этот самый стэк — произвольной глубины,

а у калькулятора Б3-34 — ограниченной: это не компьютер и ресурсов у него в

обрез. А у нас хоть и компьютер, но инструмент-то мы делаем сугубо

вспомогательный! Так что операционный стэк — пока что те же самые четыре

ячейки. (По крайней мере пока — а потом посмотрим. Но там этого вполне хватало,

думаю, что и здесь хватит.)

Стэк, если кто забыл, это "стопка" или "кипа" — способ обращения как у

пистолетного магазина: последний засунутый — лежит сверху и взять можно только

его. Но если взял — теперь наверху засунутый перед этим... Вот только у нас не

патроны, а числа, а ячеек (пока) всего четыре: при засовывании нового,

последнее пропадает, а при вытаскивании — размножается. (Но полагаться на это

таки не следует: вдруг в будущем ячеек добавим?) Главное: каждая операция берёт

свои операнды со стэка и туда же помещает результат. Кстати, очень удобно!

Не 2 + 3 = как на обычном калькуляторе, а 2 3 + и всё. Правда между 2 и 3 надо

что-то такое, чтобы указывало что ввод одного числа кончился и начался

следующего. Там была такая кнопка со стрелкой вниз — проталкивающая верхнее

число дальше в стэк. Хотя годится и любая операция — всё что угодно, что не

циферка. У нас например _ (подчеркивание), как всегда ничего не делающее.

А удобно потому, что всякие формулы, чуть сложнее 2+2 например (5+4)/(3+2)

на обычном калькуляторе считать запаришься: промежуточные результаты придётся

на бумажку записывать, а потом вводить заново. А тут: 5 4 + 3 2 + / и всё.

Кстати, это — "обратная польская безскобочная запись" называется...

В общем у наших близнецов %r и %R всё в точности то же самое: что сделать,

передаём им в виде аргумента... Мы еще не забыли, что вообще-то всё это -

внутри форматного выражения оператора Write и выглядит: Write %_%r"операции"

То есть операцию можно передать конечно и одну, а можно вот так вот: несколько

в кавычках или скобках. Любых. Но как-то интерпретатор отреагирует на другие

виды скобок, вложенные например в Write %_%r(....); которые вполне могут быть и

не сбалансированными... Так что уже лучше в кавычках.

Итак, у обоих — операционный стэк из четырёх ячеек и одни и те же операции:

& | ^ ~ побитовые: И, ИЛИ, исключающее ИЛИ, инверсия; + — * / арифметические.

Деление — целочисленное: даёт два числа — частное (сверху) и остаток (под ним).

Чтобы до него добраться (да и вообще) — операции реогранизации вершины стэка:

[ дублирование верхнего числа, ] обратная к ней — удаление его нафиг. А так же

: обмен пары и @ обмен всех четырёх — засовывание самого верхнего под низ.

Стэк у нас таки не стопка как в ПостСкрипте, а магазин фиксированной ёмкости.

(Можно было конечно и стопкой сделать, в том числе неограниченного размера.

Но тогда была бы возможна ситуация, когда на стэке ничего нет, а мы пытаемся

выполнить с этим какую-то операцию — пришлось бы как-то на это реагировать...)

Главное отличие: операции , . ; (запятая, точка, точка с запятой) — взять

очередной i-ый байт из обрабатываемой последовательности, положить его обратно

(удалив со стэка), а так же обменять их местами. (Кстати, операция 'i' сообщает

нам индекс текущей позиции, а 'l' — сколько еще осталось.) Договорились, что

если ,, или даже ,,, то значит надо взять за раз два и три байта. Или если ..

и ... то соответственно положить. А если взяли один, а положили три... Да,

тоже можно: обрабатываемый фрагмент соответственно в этом месте раздвигается.

Но уж коли мы взяли три, то i на эти три байта и продвинется... (А надо взять

еще раз, но один. И за ненадобностью выкинуть со стэка уже упоминавшейся

операцией ']'.)

Для "старшего братца" %R, который берет всю эту входную последовательность

целиком, все эти детские игры с многоточиями разумеется совершенно никчему.

Казалось бы, этим можно и ограничиться... Ну добавив еще обращения к

переменным (=X #X, где X — любая буква) и регистрам (=N #N, где N — цифра),

и еще вот эти самые перекодировки — в виде обозначающих кодировку буковок:

123 ... 1011121314
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава



Иные расы и виды существ 11 списков
Ангелы (Произведений: 91)
Оборотни (Произведений: 181)
Орки, гоблины, гномы, назгулы, тролли (Произведений: 41)
Эльфы, эльфы-полукровки, дроу (Произведений: 230)
Привидения, призраки, полтергейсты, духи (Произведений: 74)
Боги, полубоги, божественные сущности (Произведений: 165)
Вампиры (Произведений: 241)
Демоны (Произведений: 265)
Драконы (Произведений: 164)
Особенная раса, вид (созданные автором) (Произведений: 122)
Редкие расы (но не авторские) (Произведений: 107)
Профессии, занятия, стили жизни 8 списков
Внутренний мир человека. Мысли и жизнь 4 списка
Миры фэнтези и фантастики: каноны, апокрифы, смешение жанров 7 списков
О взаимоотношениях 7 списков
Герои 13 списков
Земля 6 списков
Альтернативная история (Произведений: 213)
Аномальные зоны (Произведений: 73)
Городские истории (Произведений: 306)
Исторические фантазии (Произведений: 98)
Постапокалиптика (Произведений: 104)
Стилизации и этнические мотивы (Произведений: 130)
Попадалово 5 списков
Противостояние 9 списков
О чувствах 3 списка
Следующее поколение 4 списка
Детское фэнтези (Произведений: 39)
Для самых маленьких (Произведений: 34)
О животных (Произведений: 48)
Поучительные сказки, притчи (Произведений: 82)
Закрыть
Закрыть
Закрыть
↑ Вверх