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

Еще одно такое-же типа дополнение к 4й главе


Автор:
Жанр:
Изобретательство
Опубликован:
17.03.2024 — 10.04.2024
Аннотация:
а на само деле результат очередной ревизии кода (самый конец до- и пере-писывается, а остальное - уже вряд ли)
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

"ШАБЛОН", он же "регулярное выражение" (конструкция <...>) — это только один

из элементов форматного выражения, но тем не менее отдельный язык. Впрочем,

несложный — чуть расширенный вариант шаблонов UNIX`овского sh. Отличающийся

тем, что '?' и '*' не сами обозначают один любой символ и произвольное их

количество, а наделяют таким свойством следующий после них элемент. И потому

называются "префиксами повторения". Ну и еще тем, что [...] и <...> могут

вкладываться друг в дружку как матрешки, и, соответственно, элементами

перечисления [...] могут быть не только отдельные символы, но и более сложные

конструкции. Ну и "встроенные" шаблоны конешно, типа %Буква...

Шаблон может быть "анализирующий" и "генерирующий". Анализирующий

сопоставляется с фрагментом строки (например когда с его помощью производится

операция поиска), а "генерирующий" сам формирует фрагмент строки по образчику

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

когда служит правым операндом операции вставки '*'. Удачно сопоставившийся

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

использует...

Грамматически, шаблон это аналог строчной константы. Отличается от неё

тем, что в нём нe все символы изображают сами себя, некоторые имеют

специальный смысл. В принципе таковыми можно считать все "значки", вне

зависимости от того, задействованы они в настоящий момент или нет.

Главный спецсимвол '%' — "экранирующий": он делает другие спецсимволы

(включая самоё себя) — обычными, и некоторые обычные — специальными.

Следующие по важности это префиксы повторения. Они предписывают повторить

следующий за ними элемент шаблона:

'*' — ноль или более раз

'+' — один или более раз

'?' — ноль или один раз

{N} — ровно N раз

{N,M} — не менее чем N и не более чем M раз, где N и M — числа или

фокаловские выражения, или пропущены и тогда для N — ноль, а для M — скока хошь

'-' — сразу после префикса повторения (перед повторяемым элементом)

предписывает применять не "жадный" алгоритм, пытающийся захватить сразу как

можно больше символов, а "ленивый" — действующий противоположным образом.

Таким элементом может быть:

— любой "обычный" символ (или '%' плюс специальный) — изображает сам себя

(но если это буква то с учетом предшествующего шаблону "х" или "Х")

— конструкция '%' плюс буква — встроенный шаблон (см. далее)

— символ '^' или '$' — сопоставляются с началом и концом строки

— символ '!' — сопоставляется с разделяющими строки символами ПС/ВК,

они же 'n' и 'r' с кодами 10 и 13.

— символ '.' — сопоставляется с любым символом

— символ '_' ничего не делает, но это тоже элемент шаблона

— конструкция <...> — сопоставляется если сопоставились все её элементы

— конструкция [...] — сопоставляется если сопоставился один из её элементов

Угловые <...> и квадратные [...] скобки ("последовательность" и

"перечисление") могут вкладываться друг в дружку на любую грубину. Круглые

скобки (...) пока никак не используются (оставлены про запас) но тоже

отслеживаются — т.е. их баланс тоже должен соблюдаться, так же как и для

скобок других видов. Кавычки пока никак не задействованы: <...> тоже своего

рода кавычки, отменяющие специальный смысл кавычек другого типа.

Внутри "перечисления" [...] префиксы повторения не имеют смысла, символы

'*' '?' '+' — обычные. Конструкция {N} изображает один символ с кодом N.

Но за то как и в UNIX`е есть "диапазон", например конструкция А-Я обозначает

все заглавные русские буквы. Вернее все символы, коды которых находятся в

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

буквы Ё, которая в используемой ДОС`овской кодировке — отдельно. (А диапазон

маленьких русских букв здесь вообще разрывный! Его пришлось бы обозначать как

[а-пр-я] или даже [а-еёж-пр-я].)

Кроме того "перечисление" может быть "негативным": [~...] — сопоставление

с ним считается "удачным" если не сопоставился ни один из его элементов.


* * *

Встроенные шаблоны вида %Буква сопоставляются с символами, принадлежащими

к некоторой группе:

%B %b %Б %б — любая буква, в т.ч. %Б и %б отдельно заглавная и строчная

%L %l %Л %л — любая латинская -//-

%R %r %Р %р — любая русская -//— в текущей кодировке

%D %W %K %I — русские буквы в кодировках ДОС, Win, КОИ-8, ИСО

%У %у %U %u — уникод, здесь по-другому:

%U — любой правильный символ в utf-8

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

но в любой из разновидностей уникода: по нему собственно эти

разновидности и различаются. Если сопоставился — устанавливает

внутренний признак типа уникода

%У %у — только русские буквы, и пока только в utf-8

а так же

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

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

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

но

%С %с %S %s — текстовая константа вида "..."

а прошлый раз было, но пока еще не восстановлено:

%Ч — число общего вида

%Э — правильное фокаловское выражение

%Ш — правильное форматное выражение оператора W, включая шаблон

(Подробнее — см. в справке к Фокалу выдаваемой оператором Help.)


* * *

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

"протокол", по которому генерирующий шаблон мог бы соорудить свой фрагмент.

Но который, возможно, может быть интересен и сам по себе: этот протокол

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

фрагмента строки.

Поэтому принято (временное) решение вставлять в А2 текущий (последний по

времени) протокол сопоставления шаблона операцией * с аргументом *. (Т.е.

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

значения — нет.)

Организован протокол следующим образом:

— "последовательность" <...> (в том числе и весь шаблон целиком) фиксируется в

в протоколе в виде пары скобок '<' '>', между которыми — её элементы

— любой префикс повторения "выгораживает" участок внутри последовательности,

начало которого отмечается символом '*' а конец — '|', и между ними — элементы,

с которыми сопоставилась повторяемая им конструкция. В том числе возможно что

и ни одного.

— "перечисление" [...] отображается парой скобок '[' ']', в которых

число (номер сопоставившегося элемента), запятая и то, что с ним сопоставилось.

— элемент шаблона, успешно сопоставившийся с нулём символов отображается '_'.

Это и негативное перечисление [~...] у которого не сопоставился ни один из его

элементов, и пустой шаблон '_', и '^' '$' сопоставляющиеся с началом и концом

строки

— элемент шаблона, сопоставившийся с одиночным символом 'Х' отображается в

протоколе как '.Х' — это может быть и символ, изображающий сам себя и '.'

(точка) обозначающая любой символ

— встроенный шаблон вида %Б сопоставившийся с одиночным символом 'Х'

отображается в протоколе как 'БХ'

А вот встроенных шаблонов, способных сопоставится с чем-то более сложным, у

нас пока только два: %U — сопоставляющийся с символом уникода — отображается в

протоколе как Uчисло, и %S сопоставляющийся со строчной константой в кавычках и

отображающийся в протоколе как S"..."

Что делать в более общем случае — еще надо подумать...


* * *

Генерирующий шаблон (теоретически) должен быть конгруэнтен анализирующему.

Тогда каждому его элементу достанется элемент протокола, записанный

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

Например [...] вставит элемент с тем же номером, каковой отработал в [...]

анализирующего шаблона, '*' повторит свой элемент столько же раз, сколько и

аналогичная конструкция в анализирующем, '.' вставит то, что ей досталось как

есть, а %Б с соответствующим преобразованием (например превратит доставшуюся

букву в заглавную).

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

есть пустой шаблон '_' (подчеркивание), не делающий вроде бы ничего, но элемент

протокола вставляющий и соответственно потребляющий.

Ага-ага: должен да не обязан! Очень даже запросто так может быть, что не...

Поэтому будем считать, что генерирующий шаблон сопоставляется с протоколом, а

генерируемый им текст — всего лишь побочный эффект. Ясный пень, что когда

шаблоны конгруэнтны, сопоставление будет один в один. А вот если нет, если

элементу шаблона сопоставляется чужой элемент протокола... На этот случай

разделим все элементы шаблона на "одиночные" и "множественные" — по тому,

сколько элементов протокола они бы хотели заполучить в своё распоряжение.

Множественные это <...> и *Х, а все остальные — одиночные, включая [...].

(Под * имеются в виду любой префикс повторения, а Х — повторяемый им элемент.)

Соответственно, "множественные" элементы протокола это <...> и *...| но первый

"главнее": второй только "выгораживает" себе его кусочек.

Настоящим предполагаем, что:

* множественный элемент генерирующего шаблона может "освоить" любой

доставшийся ему множественный элемент протокола, а вот с одиночными пусть

поступают по-разному:

— конструкция <...> пусть скромно предоставляет один и тот же элемент

протокола каждому своему элементу

— а конструкция *Х пусть нагло пытается захватить все доступные элементы

протокола вплоть до ближайшей закрывающей скобки '>'. Но при этом должна

"поделиться" с аналогичными конструкциями, если они есть.

* одиночные элементы...

— элементы, изображающие сами себя (обычные символы и экранированные с

помощью % спецсимволы) никак не используют доставшийся им элемент протокола.

— элементарный шаблон . (точка) вставляет это один в один, как есть. При

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

— элементарный групповой шаблон типа %Б действует так же как . (точка) для

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

(А на счет не-элементарных встроенных шаблонов еще надо подумать.)

— элементарные шаблоны _ $ ^ не порождают никакого текста.

— конструкция [...] если ей попался такой же элемент протокола, отрабатывает

указанный ею свой элемент. А если нет — самый первый.


* * *

Ну вот, вроде как всё придумал и даже почти сделал... Так, вроде бы только

кое-какие шероховатости остались. Типа что в конструкции {N,M} шаблона тоже бы

неплохо разрешить присваивание результата фокаловским переменным. Или вот, как

и для всего форматного выражения, надо бы и в шаблоне сделать %N аналогом

обращения к подпрограмме...

Ан вдруг приходит в голову мысль: а простейшие вещи, типа сравнения двух

строк на полное совпадение с помощью этого замудренного механизма — как?

Оказывается, у нас нету бинарных операций со строками — все унарные.

Нет, вставить одну строку внутрь другой, или найти совпадающий с ней фрагмент,

это пожалуйста. (Помести её заране в регистр, и...) Даже на полное совпадение

особого труда не составляет. В том числе, по желанию, игнорируя или нет

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

#7 или {:7}, а {:7$}, чтобы и конец строки захватить. А дальше — постфикс

какой ни будь...)

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

(типа: какая "больше", то есть позже по алфавиту?), или найти наибольшую общую

подстроку — то, что для третьего Фокал задумано как "полукорреляция" (на

предмет вот так доопределить для строк операцию ^)...

// Но тут наступило утро и Шахеризада завершила дозволенные речи //

================


* * *

===============

// а всё что дальше — рассуждалка типа "как бы нам обустроить..." //

// так что далее читать не следует, а то такого можно начитаться...! //

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

"с разбегу" преодолеть некий логический барьер. Прошлый раз это были вот те

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

структурированным данным. Таким, как например поля заголовка пакета им.тов.

Залётова, или записи реляционной базы данных из файла типа *.dbf

Структура — это вам не строчка: она — набор полей, в каждом из которых — по

такой вот строчке... Или по числу. Или исчо что — ну вот ссылка например...

На что-то...

Ага-ага: для чисел у нас аккумулятор А1, для строчек А2, а для ссылок

выходит что А3, так? С А1, а вернее с числами работает весь базовый Фокал,

с А2 тоже вроде как научились, а теперь очередь А3 подходит...

Поэтому мысль номер один — считать тип очередного поля в некую переменную,

а значение в это время нехай сразу окажется в одном из аккумуляторов. Только

вот синтаксически это оформить — как?...

Ну например Ask :имя_поля: = Т; или даже Ask :имя_поля: = Т, Р, П...

Где Т — тип поля: 0 — число, 1, строка, -1 — ссылка

Р — размер (для строки) и какие ни будь признаки для остальных типов.

В том числе -1 если ссылка — "нулевая", никуда не указывает. Иначе, например,

размер потока (файла), или записи, на которые ссылка. Следующие переменные,

если есть — еще какие либо параметры. (Порядковый номер поля, его смещение от

начала записи, набор неких аттрибутов...) Но '=' только при двойной

буферизации, иначе ошибка.

Тащить '=' в оператор Ask, где его раньше никогда небыло, конешно не есть

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

полю тупо тащить его содержимое в А2, а в А1 например его тип, как я хотел

раньше, то как это отличить от просто перехода к следующему табулостопу,

никак не изменяющему содержимое аккумулятора? (Даже если первое исключительно

для файлов с двойной буферизацией, а второе — без таковой. И смешивать их не

предполагается.)


* * *

ПРО ЗАПИСИ И ПОЛЯ ОНЫХ

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

значению. А вот каковы типы этих значений, привязан ли тип к данному полю,

или может меняться по нашему произволу — в зависимости от того, какое

значение мы в это поле запишем; фиксирован ли и при этом упорядочен ли каким

то образом сам набор полей, или тоже — предмет нашего произвола — пусть всё

это пока остаётся за кадром. Потому что в одних случаях так, а в других эдак.

В каком ни будь Питоне или Луа, интерпретируемых языках с полиморфизмом,

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

только вздумается типа (разумеется из тех, которые есть) — потому что код

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



Иные расы и виды существ 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)
Закрыть
Закрыть
Закрыть
↑ Вверх