KRIEGSSPIELE!
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.

Получение символа - EXPECT И WORD

Перейти вниз

Получение символа - EXPECT И WORD Empty Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:45 pm

Что умеет настоящий интерпретатор, чего не умеет наш "Цикл Управления"? Интерпретатор всегда знает, что именно он читает - программу, команды управления, пользовательский ввод. А если он оконный - то и системные события - нажатия кнопочек и выбор менюшек...
Если угодно, это "понимание" было даже у первых программируемых калькуляторов.
Наш же цикл устроен совершенно неправильно - он, дурак, думает, что все все внешние события, выраженные в командах, поступают ему на вход однородным нескончаемым потоком, навроде ленты машины Тьюринга, разбитой на аккуратные клеточки: одна клетка - одна команда. Знай себе, щелкай.
И наша цель - поддерживать его в этой уверенности. Ведь, есть программа "Щелк" - "считай слово - сдвинься к следующему" - в FORTH она называется WORD - и... все.
Весь ввод, который попадает в FORTH-систему проходит сквозь это игольшое ушко. (Конечно, если подумать, то т.к. простейшая FORTH-система содержит в себе всего-то десяток слов, то в обработке всего ввода одним словом нет ничего странного).
По-сути, это аналог файла или сообщения ОС - может быть "пропихнуто" через WORD, значит доступно для обработки FORTH.


Последний раз редактировалось: Gudleifr (Сб Мар 02, 2019 11:05 am), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:45 pm

БЕСКОНЕЧНЫЙ ПОТОК  

К сожалению, в дикой природе очень редко встречаются устройства, способные снабжать нашу программу непрерывным потоком однотипных данных. Даже пользователь норовит после каждого предложения возврат каретки поставить. Или даже требует виртуальных вентилей и тумблеров, чтобы ничего не вводить, а только мышкой тыкать. Проблема усугубляется, если программа вынуждена читать из нескольких источников разом.
Конечно, это, в основном, проблема операционной системы, но две вещи наш "Щелк"-WORD, все равно, обычно, уметь должен.
Он, во-первых, должен уметь отличать пробелы от символов (т.е. понимать, что всякие тайм-ауты, переводы строки, табуляции и прочие технические ограничители - суть, разновидность пробелов, т.е. что-то, что "разделяет слова").
Во-вторых, WORD должен уметь определять конец потока команд.
Обычно, все реализации WORD, которые распознают текстовый поток слов, умеют первое, а второе реализуется выходом из одного из вложенных циклов интерпретации (см. OK - Интерфейс с ОС - Получение символа - EXPECT И WORD Leaf10ТЕМА #39Получение символа - EXPECT И WORD Leaf10).


Последний раз редактировалось: Gudleifr (Сб Мар 02, 2019 11:13 am), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:46 pm

ВТОРИЧНАЯ УТИЛИЗАЦИЯ WORD

Я уже упоминал слова - "нестандартные интерпретаторы", умеющие самостоятельно читать входной поток ("обороты"). Так вот, практически все они используют слово WORD (или тоже самое - PARSE, но об этом позже), только потом либо не вызывают FIND, либо компилируют/исполняют своим особым способом.
Так, что не только стандартный FORTH-интерпретатор все делают через WORD, но и большинство стандартно-нестандартных. Это автоматически позволяет добиться того, чтобы обороты читались с точки зрения пользователя точно так же, как и "обычные слова" - например, точно так же реагируя на переводы каретки или клавиши забоя...
WORD - единый способ чтения данных FORTH-системы. И это, хотя и удобно в очень многих областях применения FORTH-системы, но может совершенно не соответствовать тому, что вам понадобилось именно сейчас.
Впрочем, ничего страшного, единственное, что не дает прицепить к FORTH-системе свой совершенно по-особому устроенный интерпретатор - инерция мышления.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:46 pm

"КАК ЕСТЬ"

Случайно обнаружил еще один способ применения WORD - считывать из ПОТОКА СЛОВА и отправлять их в буфер "как есть". Нет, конечно, во времена БЛОКОВ такое было в порядке вещей... Но мне понадобилось с совершенно другой целью - отложить исполнение/компиляцию вводимого фрагмента ПОТОКА до лучших времен. Для реализации концепции программирования "сверху вниз". Причем, т.к. БЛОКОВ уже давно нет, то проще всего организовать буфер в СЛОВАРЕ, особенно, если вершина словаря и так уже используется как временный буфер для WORD.
***

Вообще же восприятие WORD вводимого фрагмента "как есть" - без интерпретации (сюда же попадают комментарии и строковые константы), делает остановку WORD в конце строки (КОНЕЧНЫЙ ПОТОК) крайне нежелательной. Приходится создавать дополнительный цикл доввода предложения (оборота).
***

Для Win32Forth имеем что-то вроде:

: BLOCK-HERE CREATE HERE 0 , 0 BEGIN \ НАЧАТЬ ЧТЕНИЕ В БУФЕР
BEGIN BL WORD DUP C@ 0= WHILE DROP REFILL DROP REPEAT \ ЧИТАТЬ СЛОВО
DUP COUNT S" BLOCK-END" COMPARE WHILE \ ДО МЕТКИ "END-BLOCK"
DUP COUNT HERE SWAP CMOVE C@ DUP ALLOT + 1+ BL C, \ ПЕРЕНОС СЛОВА
REPEAT DROP SWAP ! DOES> LCOUNT EVALUATE ;

Теперь можно написать:

BLOCK-HERE ЭТО-БУДЕТ-ТАК
ДУМАТЬ
ДЕЛАТЬ
: МЕЧТАТЬ ФАНТАЗИРОВАТЬ ;
МЕЧТАТЬ
END-BLOCK

: ДУМАТЬ ;
: ДЕЛАТЬ ;
: ФАНТАЗИРОВАТЬ ;

ЭТО-БУДЕТ-ТАК


Последний раз редактировалось: Gudleifr (Вт Апр 27, 2021 12:31 am), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:47 pm

WORD И PARSE

Алгоритм действия WORD исторически описывают так: снять со стека символ (пробел), пропускать все такие символы, пока не встретится другой (пропуск пробелов перед словом), считывать все другие символы, пока не встретится опять исходный (считывание слова до пробела).
Тут уже кроется ошибка. Дело в том, что в случае пустого слова мы не понимаем, что оно уже кончилось, и думаем, что все еще читаем пробелы перед словом.
Например, введем слово, читающее строку и что-то с ней делающее:

: СТРОКА" 34 WORD что-то-делаем ;
СТРОКА" Сам дурак!" \ работает нормально
СТРОКА" " \ все еще ждет, когда же закончится слово

Проблема в том, что во втором случае слово кончается раньше, чем WORD начинает пропускать "пробелы".
Для этого придумали слово PARSE, которое делает все тоже самое, но пробелы до начала слова не пропускает. Т.о. программист теперь обязан знать заранее, что ему важнее - пропустить пробелы или отловить пустые слова.
На мой взгляд проблема не стоит выеденного яйца. Как уже писал выше, WORD обязан различать различные "пробельные символы" как пробелы. Т.е. обрабатывать последние специальным образом. Почему, в таком случае, не считать пропуск пробелов перед словом специфической реакцией именно при введении пробела как ограничивающего символа. А для других символов - читать слово сразу.
И, действительно, придумать причину пропускать что-либо, кроме пробелов достаточно сложно: например, пустой символ в начале ленты памяти, код пустой операции в коде программы, пустые блоки памяти, области фонового цвета в видеопамяти... Все эти случаи настолько далеки от "текстового ввода", что написание для них особого WORD, вроде бы, и не особенно раздражает.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:48 pm

ИТАК, WORD

Он должен:
1. Знать, где лежит курсор, указывающий, откуда читаем.
2. Настраиваться на конкретный вид пробела.
3. Уметь особым образом работать с целым классом символов, приравниваемых к "обычному пробелу".
4. Пропускать пробелы перед началом слова. Другими словами, определять в потоке начало слова.
5. Считывать слово в специальное место памяти для дальнейшей обработки. Это нужно, чтобы не портить поток при чтении, но может применяться и для каких-нибудь сложных процедур распознавания. Удобно сразу разместить копию вершине словаря - для экономии времени создантя новой словарной статьи.
6. Определять в потоке конец слова.
7. Определять в потоке конец самого потока. Причем, в случае, если вообще ничего не удалось прочитать, возвращается некое "совсем пустое слово". Интрига здесь в том, что такое слово может быть засунуто в поток специально, и интерпретатор не будет знать, ничего не ввелось или специально введено "ничего". Этим пользуются для организации специальных временных потоков (например, чтения блоковой памяти).
8. В случае, если поток кончился раньше читаемого слова, как-то об этом сигнализировать (или самостоятельно довводить в поток еще кусочек ввода). Обычно WORD этого не умеет, и если есть подозрение, что слово может занимать более, чем одну строку, приходится окружать WORD сложными циклами (см. цикл с REFILL в примере выше).
9. Если поток не кончился, то переставить курсор на примерное начало следующего слова.

Может показаться, что столь богатое на функционал слово удобно будет разбить на элементарные слова-подпрограммы... Не тут-то было, на языке ассемблера оно пишется гораздо удобнее. А так как похожих слов (кроме избыточного PARSE) не существует, то введение подпрограмм здесь не окупится.
(Кстати, если WORD переписать на языке ассемблера, отпадает и потребность использование в ядре FORTH слова CMOVE).
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:49 pm

ПАРСИРОВАНИЕ ВХОДНОГО ПОТОКА

Рассмотрим различные форматы разбора входных (текстовых)строк:
- накладывание на строку некоего шаблона (как в FORTRAN или C);
- связывание входной строки с регулярным выражением (вплоть до полноценного лексического разбора - полного разбиения строки на лексемы);
- грамматический анализ строки (т.е. построение полного дерева разбора с учетом взаимного расположения лексем и их контекстной зависимости).

В традиции FORTH - ограничится только последовательным чтением лексем (слов). Грамматику пусть обеспечивают сами слова при своем исполнении. А вот, что предпочесть: тупой поиск ограничителя (как в FORTH), шаблоны или регулярные выражения? Первые два, на самом деле, лишь разновидности третьего. Понятно, что регулярным выражением я могу описать всю строку разом, но, может быть, его можно разбить на атомы?

1. пропускаемые символы (не влияющие на информацию, извлекаемую из строки);
2. позиционирующие символы (обозначающие начало какого-либо информационного поля);
3. ограничители (обозначающие конец информационного поля и/или строки);
4. шаблоны присутствия (возвращают сигнал наличия/отсутствия данного поля в строке);
5. информационные шаблоны (возвращают значение, записанное в этом поле).

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

- позиционирующие символы ("пробелы" перед словом);
- информационные шаблоны (слово);
- ограничители (конец буфера ввода).

На первый взгляд, сложность только с третьим шаблоном: он может быть представлен двояко - спецлитера/сигнал или выход за пределы буфера чтения (проверка счетчика). И то, и другое может прервать распознавание первых двух шаблонов. Как мы уже неоднократно видели, возможен и третий случай: когда поток не может закончиться (мы заведомо закончим его интерпретировать раньше).
***

На второй взгляд, могут возникнуть сложности еще двух видов:
а) наличие многочисленных вариантов информационного шаблона: например, в программах, написанных на языке Trac: "(", "строка, ограниченная парной скобкой", ",", "#(", "##(", "# и что-то другое", ")", "другая литера";
б) наличие знаков препинания в естественных языках.
***

Со всеми этими сложностями разобраться вроде бы легко, но универсального лекарства не видно.
Но оно и не нужно! Проще для каждого нового случая иметь свой интерпретатор. (Т.е мы не столько отказываемся от регулярных выражений, сколько компилилируем распознающий их код "в уме", ибо он тривиален).
А то, ведь, многие фортеры и впрямь дают возможность переопределить распознаватели всех тех пяти "атомов", что перечислены выше, в рамках применения стандартного WORD.
Еще надо учитывать, что всякого рода "анализ" слова, например, обрезание суффикса-окончания, или разбиения на подслова, естественно смотрится не в WORD, а следующих за ним процедурах распознавания - FIND и NUMBER, пусть, они, даже, и вернут управление WORD, заставив его "перенастроиться".
***

Тут, пожалуй, важно вовремя отказаться от того, что "исторически сложилось":
1. Различают "пробелы" и "прочие символы". Если ищется слово, ограниченное "прочим символом", то ищется именно эта конкретная литера. Если же указан "пробел", то ограничителями считаются все "пробельные символы": пробелы, табуляции, возвраты каретки, переводы строк... (См. выше).
2. Почему-то никто не догадался, что пропускать "ведущие пробелы" имеет смысл только в случае использования "пробельных символов" (см. предыдущий пункт). Пропуск ведущих "прочих символов" очень маловероятен. (См.выше).
3. Есть две крайности: слова, которые надо выдергивать из текстового ввода и адреса слов в шитом коде. Когда-то они просматривались в едином Цикле Управления, но уже очень давно это два разных цикла (См. СЛЕДУЮЩИЙ). А как быть если "поток слов" представлен в некоторой промежуточной форме? Например, поток системных сообщений - и "поток", и распознавать особо не надо.
Я предлагаю считать особым только "поток" шитого кода (ввиду его "самоинтерпретируемости"), а все остальные случаи считать обычными разновидностями ПОТОКА.


Последний раз редактировалось: Gudleifr (Вт Июл 04, 2023 10:41 am), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:50 pm

ДРУГИЕ ВАРИАНТЫ

Не будем здесь опять поднимать вопрос о том, откуда "на самом деле" приходит разбитый на слова поток, который FORTH-система интерпретирует.
И даже не будем думать о том, имеем ли мы связный последовательный поток слов-команд от пользователя, или асинхронный поток слов-сигналов от операционной системы.
Все эти случаи сводятся к "обычным" потокам. Займемся необычными.


Последний раз редактировалось: Gudleifr (Вт Мар 12, 2019 1:08 pm), всего редактировалось 1 раз(а)
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:50 pm

ТИХО САМ С СОБОЮ...

Подумаем, а не может ли FORTH-система общаться словами сама с собой.
Прецеденты есть, например, Windows-программа умеет анализировать простейшие системные события, чтобы вовремя послать самой себе сигнал о какой-либо осмысленной их комбинации: например, нажатие-отпускание кнопки распознается как ее срабатывание, а специальные комбинации клавиш - как синонимы команд меню.
Происходит нечто подобное и в различных моделях искусственного интеллекта, где возбуждение нескольких "простых символов" порождает возбуждение "сложного".
FORTH-система действует изначально совершенно обратным образом - разлагая вызов сложных слов на вызовы слов простых.
***

Конечно, почти всякий уважающий себя интерпретатор имеет возможность написать строчку "на самом себе" и затем ее выполнить. В FORTH-Стандарте ANSI-94 даже есть специальное слово - EVALUATE.
***

Зачем это может понадобиться? Например задача естественно разлагается на фазу анализа и фазу выполнения, причем обе требуют большой затраты ресурсов. В этом случае имеет смысл результатом выполнения первой фазы считать программу, которая выполнит вторую.
Или, доведя до логического завершеня тезис об удобстве хранения данных в текстовом виде, мы придем к идее хранения данных в виде FORTH-текстов... (Мы даже не будем здесь первыми: так хранятся базы данных в Perl, так работают различные XML-хранилища...)
***

Но, как я уже где-то поминал (или еще упомяну), FORTH умеет читать свой язык, но не умеет на нем писать. Пригодные для этого слова - ID. (напечатать имя слова), и >NAME (получить имя слова) исключены из Стандарта.
Поэтому формировать строку для EVALUATE "изнутри" никому и в голову не приходит.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:51 pm

КАК ОН ДЫШИТ, ТАК И ПИШЕТ...

Современные фортеры предпочитают говорить о FORTH-компиляторах, а в последних практически единственный способ организовать что-то подобное - использовать механизм конечных автоматов.
***

Но не в FORTH! Он способен не только самому себе что-то написать, но и на ходу сгенерировать сам себе шитый код.
Правда, и то, и то только в потенции.
Классических примера "умной компиляции" всего два:

1. INTERPRET, компилируя числовой литерал, выбирает код в зависимости от распознанного типа - одинарного, двойного или вещественного... Строковые литералы INTERPRET уже не понимает...
2. Идея целевой компиляции, вроде бы, предполагает принятие некоторых решений "что включать, а что - нет". Но то, что авторы Стандартов радостно галдят о модулях и условной компиляции, наводит мысль о торжестве ручного управления...

Все компилирующиеся фрагменты создаются только программистом/пользователем. Если и создается слово, способное создавать другие слова, то семантика исполнения последних, все равно, явно описывается заранее.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:51 pm

И ГЕНИЙ - ПАРАДОКСОВ ДРУГ

Вообще же, программы, способные писать другие программы, давнишняя мечта программистов... Почему же, получив в свое распоряжение FORTH-систему, где это так просто, они этого не делают?
***

Если мы вспомним изначальную статью Дейкстры, мы там увидим стек, трактуемый не только как механизм обмена данными между словами, но как место сохранения кода, подлежащего выполнению или записи в словарь. Т.е. код можно изначально создавать и изменять прямо на стеке! Не хакерски "перехватывая его где-то по дороге", а там, где "положено"!
Недаром же Дейкстра предложил свою модель как окончательный формализм модели вычислений.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Получение символа - EXPECT И WORD Empty Re: Получение символа - EXPECT И WORD

Сообщение автор Gudleifr Пт Сен 15, 2017 3:52 pm

И ЗВЕЗДА С ЗВЕЗДОЮ ГОВОРИТ...

Возвращаясь к модели программного формирования потока, очевидно приходим к идее обмена таким способом данными между разными FORTH-программами.
Тут мы опять натыкаемся на "псевдосистемность" FORTH. С одной стороны, фортеры настаивают на том, что FORTH "почти операционная система", с другой, он в общении с внешним миром ведет себя не лучше обычного BASIC. Его легко реализовать в любой операционной системе, но такой подход не позволяет говорить ни о каких самостоятельных "системных решениях".
***

В "Интерфейсе с ОС" (Получение символа - EXPECT И WORD Leaf10ТЕМА #39Получение символа - EXPECT И WORD Leaf10) показано, что решением проблемы интеграции FORTH в ОС (или написании FORTH-ОС) не может быть
ни ориентация только на процессы или только на сообщения (мы, ведь, гордимся универсальностью FORTH),
ни на что-то настолько тупое (BASIC), что "легко эмулировать" (мы, ведь хотим пользоваться благами ОС).
И решение здесь видится единственное - легко ложащееся и на процессы-файлы и на очереди сообщений: понятие ПОТОКА, откуда читает WORD. Т.е. подобно тому, как адрес кода слова является воплощением "единицы действия", то имя слова - воплощением "единицы обмена", файлом и/или сообщением, если потребуется...
***

В самом простом случае мы имеем несколько FORTH-машин в рамках одной FORTH-системы, работающих как подпрограммы или сопрограммы или (в этом случае они могут обмениваться EVALUATE-строками или совместно разделять некоторые данные, или обрабатывать данные проход за проходом).
Но, т.к. правилом для FORTH является максимальная простота, то до реализации полноценных "потоков слов" дело обычно не доходит.
***

А вот для обмена данными между разными FORTH-системами (что бы из себя не представляла операционная система, в которой они работают), потоки должны быть реализованы честно. И нам будет проще не добавлять к FORTH несуразные модули, а задуматься, что будет называться "словом" в нашем случае.
Gudleifr
Gudleifr
Admin

Сообщения : 3241
Дата регистрации : 2017-03-29

Вернуться к началу Перейти вниз

Вернуться к началу

- Похожие темы

 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения