Мне как-то долгое время не сильно нужны были позиции начала и конца лексем и поэтому я их никуда не собирал, но сейчас при разработки фичи "инкрементальный парсер" добавил их довольно быстро, правда с самим инкрементальным парсером застрял, но планирую как-нибудь выкатить это всё на публику, будет примерно так:
struct t_node_base{int start=-1,end=-1;};
и далее все лексеры наследуются от этой базы.
Если нужна эта фишка поскорее - пишите, выложу.
очень много строковых операций
Да, много, но это всё надо чтобы дизайн парсера был красивым и удобным, если от этого отказаться, то всё превратиться в оптимизационный ад и ещё может потеряться фишка "сохранения обратно в строку" которая очень важна для конвертеров между разными форматами.
заходит подход через описание всех токенов в enum, ближе к низкому уровню.
Да, я умышленно в этом месте пожертвовал скоростью ради удобства + теперь не могу заводить токены и enum`ы :)
Надеюсь когда-то смогу за счёт красивой архитектуры автоматически подменять строки на токены/enum в коде, но пока эта идея из области фантастики.
PS: Процитированный вами код - это не сгенерированный код, а вручную написанный код для обхода полученного AST, но посыл/вывод полностью верный.
ближе к низкому уровню
Надеюсь вам/всем когда-то надоест эта близость с железом и вы продадите её временно ради удобства и мы вместе сделаем ещё что-то толковое.
Если вдруг кому-то/вам надоест писать парсеры вручную и захочется делегировать/разделить эту задачу с кем-то, то пишите мне я попробую помочь сделать эту часть работы на 5+(в плане архитектуры строготипизированного AST).
А у вас есть какие-то прорывные идеи в дизайне языков программирования? Если вам не жалко ими поделиться, то я бы с радостью хотел их увидеть одним из первых.
не знаком с шарпом, но судя по вашему описанию у вас будет раздутый(из-за постоянного перечисления одних и тех же имён полей объектов) формат файл сохранения по сравнению с моим бинарным. а ещё json-формат должен проигрывать по скорости загрузки/сохранения.
Вы кажется не поняли аналогию. Достижение некоторого НОВОГО знания будет пупыркой, которая закономерно строилась на основе каких-то предыдущих знаний.
Ну если на новое знание смотреть как на точку рядом с шариком где все знания это точки, то конечно оно будет выглядить как точка. Из этого надо сделать вывод что мы выбрали неправильную точку зрения и надо смотреть на другую проекцию наблюдаемого нами многомерного пространства знаний, на такую точку зрения где знания это ветки дерева/сетей и где достижение нового знания сразу же открывает нам ворота/почки для новых отростков практически на всём дереве/сети и можно тут же получать от него кучу профита, т.к открытие в одной области сокращает путь к открытию в других областях знаний совершенно неожиданно.
В ПО всё обычно сводится к оптимизации последовательностей map/reduce. ... Вот где-то между двумя этими крайностями и приходится лавироват, чтобы получать прибыль и развиваться
Очень интересная точка зрения, никогда о таком не задумывался, спасибо, теперь моя мрачная версия картины мира пополнится ещё и этим ограничением/знанием.
Если сместить фокус на уровень выше по отношению к нашим программам - то мы открываем для себя доступ к новом недоступным нам ранее оптимизациям. Речь уже не об оптимизации отдельных последовательностей идущих на вход наших программ, а об оптимизации процессов в которые наши программы встроены и языков/форматов на которых описывается вся цепочка обработки информации. Меняя эти языки/форматы и правила порождения задач, мы меняем не одну последовательность, а всё пространство возможных решений. Таким образом мы можем экономить не только время выполнения наших программ и получать с этого профит, а время тех кто эти последовательности входящие в наши программы сгенерировал и время тех кто занимается интерпретацией результатов работы наших текущих программ.
Про майнинг крипы даже не думал пока писал статью.
В области разработки программных алгоритмов это нифига не маленькая пупырышка, а огромная ветка от ветвистого дерева знаний где есть куча хитрых связий окутывающих всё дерево.
Насчёт потребляемых ресурсов не уверен, но вроде в области разработки алгоритмов потребление не такое уж и огромное по сравнению с другими пассивными статьями расходования ресурсов не направленных на исследования. Конечно их можно включить в затраты на исследования и тогда всё уже не так весело.
Про внедрение - даже сказать нечего, т.к алгоритмы внедрять тоже дорого получается. Вся надежда на ИИ что он сможет у себя внедрять алгоритмы практически бесплатно.
Вот если бы Ü был дружелюбен для разработки достойной системы сериализации/RTTI/толковых_умных_указателей/генерации_парсеров и на нём можно было повторить например разработку такой истории как тут, то тогда было бы понятно как переманивать программистов с других языков программирования.
вроде ничего специально не обфусцировал и просто выложил почти все свои исходники почти всех проектов(уже много лет назад), сейчас просто решил написать к ним статьи/документацию и пошарить на публику, вдруг какая-то толковая аудитория увидит/оценит/присоединится/поможет.
я исхожу из того, что вероятность найти полезных людей через открытую публикацию выше, чем риск пострадать от тех, кто просто хочет что-то утащить на халяву.
почему до сего дня производства повально не автоматизированы?
наверно потому что тот кто ответственен за повальную автоматизацию пока не видит в этом смысла/профита. да и зачем спешить? можно дать всем шанс автоматизировать всё самостоятельно, а не насильно. если интересно вот чуть больше инфы по теме(там два сообщения от меня и два от ИИ): https://chat.deepseek.com/share/hexvsm55d4xueez6mh
ИИ подсказывает что вы хотите узнать зачем вам вообще мигрировать типы, если можно описывать всё через таблицы и каждый раз собирать сцену заново? То есть вы предлагаете перейти на декларативную сборку сцены тому кто занимается задачей "миграцией долгоживущего состояния сцены + эволюции типов"? Если так то спасибо за идею, но мне мой подход больше нравится. почему/зачем я так делаю/сделал? - потому что раньше мне казалось что это путь к идеальной архитектуре программ, а перестирать сцену каждый раз - это слишком простой/слабый/тупиковый путь. сейчас я менее категоричен и вижу плюсы обоих подходов и думаю что будущее за гибридным решением.
попросил ИИ перевести на понятный мне язык, вот его цитата:
«Я понял, что вы не сериализуете стек и выполнение. Тогда, если уж есть описание состояния, его можно:
представить как байткод
патчить
при желании транслировать в нативный код
Но для этого придётся сделать язык + VM + транслятор, то есть фактически DSL, а не просто сериализацию данных. Это сложно, похоже на изобретение велосипеда, но в итоге можно получить мощный комплекс отладки и патчинга.»
интерпретация от ИИ:
Он согласился с тобой, но:
не может выйти из парадигмы «всё = код»
поэтому постоянно тянет разговор к VM / DSL / байткоду
Ты же работаешь в другой оси:
данные эволюционируют
код остаётся нативным
Он этого ментально не различает.
вот что я думаю читая это:
что бы я сделал если бы нашёл кого-то кто про финансирует open-source разработку? - свой язык программирования который сразу без танцев с макросами и шаблонами понимает мою систему RTTI/STTI/указатели и при миграции между форматами генерирует настоящий нативный код для сохранения и загрузки состояния в этом новом формате, плюс ещё если к этому добавить safe_eval+unsafe_eval, то вообще было бы шикарно.
мы здесь не сериализуем некоторые вещи связанные с выполнением программы, а именно: не сохраняем стек вызовов не сохраняем PC / позицию выполнения не трогаем низкоуровневые детали вроде сетевых или GPU-состояний
мы тут сериализуем почти всё состояние данных, включая ссылки и типы, чтобы: обновлять бинарь мигрировать структуры продолжать работу без VM
VM/JIT решают другую задачу - управление кодом, а не миграцию данных между версиями типов.
для этого придумали скриптование. делаете какой-нибудь ctrl+r и триггерите переинициализацию скрипта. hotreload никогда не требовал сериализации графа.
Ну чистая правда, даже придраться не к чему. Хотя есть: скрипты - это иногда медленно; структуры данных внутри скриптов также может меняться и ломать миграцию молча и противно. Можно попробовать парировать отсылкой к JSON-based системам миграции, но это опять же медленно и не лишено кучи недостатков.
заводите класс реестра ресурсов и просто ссылаетесь на ресурс по некоторому составному id - resource id + offset id. В качестве resource id можно взять например djb2 хэш от пути к ресурсу. Offset id зависит от того как вы получаете конкретный элемент в ресурсе. Пару широких интов определённо проще сериализовать чем возиться со ссылочными типами, которым ещё некоторую персистентность надо навести.
100% правда. я так поступил из-за своего неумения проектировать программы. я даже не могу возразить что у меня есть плюс - типа мои ссылки быстрее работают, а вот нифига, id+hash рулят и педалят походу. Всё что меня спасает - это отсутствие коллизии хэшей вообще.
Так а используется-то оно как? Выглядит как несколько странный дебаггинг, судя по вашему описанию.
Используется при миграции между форматами.
Ну, вы же решали какую-то свою боль, изобретая вот это вот всё.
ну я научился сохранять всё состояние программы со всеми ссылками и метаинфой, получил крутую миграцию. боль была в том, что предыдущая система сериализации не умела сохранять обычные не полиморфные типы данных. А это очень полезно для работы по сети, т.к там требуется компактность и скорость. В скорости я проиграл из-за того что интерпретирую метаинформацию при обходе дерева/графа, а вот компактность получил. Правда для сети мне оказались ссылки не нужны и поэтому я сделал ещё одну версию сериализатора без них. И она победила из-за своей скорости компиляции.
Сделайте минимально воспроизводимую боль. Пусть без окон и imgui крутилок, но понятную другим.
ИИ подсказывает что можно сделать демонстрацию профита от моей системы на примере системы из publisher-subscriber и их миграции в новый формат. Попробую сделать. Спасибо за то что навели на хорошую идею примера!
“Unfortunately POST++ due to its simplicity provides no facilities for automatic object conversion”
POST++ — это persistent object store на mmap, а не сериализация с миграциями. Он предполагает стабильный layout, адреса и не поддерживает автоматическое изменение типов. В моей задаче ключевыми были самоописание формата и обновление бинарника без потери данных, поэтому подход принципиально другой.
тогда проще написать виртуальную машину, если есть требование такой отладки
виртуальная машина не решает проблемы миграции данных между разными(старой и усовершенствованной) системами типов, но зато позволяет менять код что очень круто, правда, как вы верно заметили, ценой замедления программы в 10-50 раз, что для меня не приемлемо.
тоже стало интересно и тут меня тоже на этой теме понесло в далёкие края: https://gamedev.ru/flame/forum/?id=294016
Мне как-то долгое время не сильно нужны были позиции начала и конца лексем и поэтому я их никуда не собирал, но сейчас при разработки фичи "инкрементальный парсер" добавил их довольно быстро, правда с самим инкрементальным парсером застрял, но планирую как-нибудь выкатить это всё на публику, будет примерно так:
struct t_node_base{int start=-1,end=-1;};и далее все лексеры наследуются от этой базы.
Если нужна эта фишка поскорее - пишите, выложу.
Да, много, но это всё надо чтобы дизайн парсера был красивым и удобным, если от этого отказаться, то всё превратиться в оптимизационный ад и ещё может потеряться фишка "сохранения обратно в строку" которая очень важна для конвертеров между разными форматами.
Да, я умышленно в этом месте пожертвовал скоростью ради удобства + теперь не могу заводить токены и enum`ы :)
Надеюсь когда-то смогу за счёт красивой архитектуры автоматически подменять строки на токены/enum в коде, но пока эта идея из области фантастики.
PS: Процитированный вами код - это не сгенерированный код, а вручную написанный код для обхода полученного AST, но посыл/вывод полностью верный.
Надеюсь вам/всем когда-то надоест эта близость с железом и вы продадите её временно ради удобства и мы вместе сделаем ещё что-то толковое.
Если вдруг кому-то/вам надоест писать парсеры вручную и захочется делегировать/разделить эту задачу с кем-то, то пишите мне я попробую помочь сделать эту часть работы на 5+(в плане архитектуры строготипизированного AST).
А у вас есть какие-то прорывные идеи в дизайне языков программирования? Если вам не жалко ими поделиться, то я бы с радостью хотел их увидеть одним из первых.
Что думаете насчёт того чтобы использовать готовый генератор парсеров который на выходе сразу даст вам строготипизированное AST на C++?
не знаком с шарпом, но судя по вашему описанию у вас будет раздутый(из-за постоянного перечисления одних и тех же имён полей объектов) формат файл сохранения по сравнению с моим бинарным. а ещё json-формат должен проигрывать по скорости загрузки/сохранения.
Ну если на новое знание смотреть как на точку рядом с шариком где все знания это точки, то конечно оно будет выглядить как точка. Из этого надо сделать вывод что мы выбрали неправильную точку зрения и надо смотреть на другую проекцию наблюдаемого нами многомерного пространства знаний, на такую точку зрения где знания это ветки дерева/сетей и где достижение нового знания сразу же открывает нам ворота/почки для новых отростков практически на всём дереве/сети и можно тут же получать от него кучу профита, т.к открытие в одной области сокращает путь к открытию в других областях знаний совершенно неожиданно.
Очень интересная точка зрения, никогда о таком не задумывался, спасибо, теперь моя мрачная версия картины мира пополнится ещё и этим ограничением/знанием.
Если сместить фокус на уровень выше по отношению к нашим программам - то мы открываем для себя доступ к новом недоступным нам ранее оптимизациям.
Речь уже не об оптимизации отдельных последовательностей идущих на вход наших программ, а об оптимизации процессов в которые наши программы встроены и языков/форматов на которых описывается вся цепочка обработки информации.
Меняя эти языки/форматы и правила порождения задач, мы меняем не одну последовательность, а всё пространство возможных решений.
Таким образом мы можем экономить не только время выполнения наших программ и получать с этого профит, а время тех кто эти последовательности входящие в наши программы сгенерировал и время тех кто занимается интерпретацией результатов работы наших текущих программ.
Про майнинг крипы даже не думал пока писал статью.
В области разработки программных алгоритмов это нифига не маленькая пупырышка, а огромная ветка от ветвистого дерева знаний где есть куча хитрых связий окутывающих всё дерево.
Насчёт потребляемых ресурсов не уверен, но вроде в области разработки алгоритмов потребление не такое уж и огромное по сравнению с другими пассивными статьями расходования ресурсов не направленных на исследования. Конечно их можно включить в затраты на исследования и тогда всё уже не так весело.
Про внедрение - даже сказать нечего, т.к алгоритмы внедрять тоже дорого получается. Вся надежда на ИИ что он сможет у себя внедрять алгоритмы практически бесплатно.
Простого typeinfo из Ü/С++ пока недостаточно, т.к они например не захватывают информацию о выражении которым инициализируются поля структур/классов.
Вот если бы Ü был дружелюбен для разработки достойной системы сериализации/RTTI/толковых_умных_указателей/генерации_парсеров и на нём можно было повторить например разработку такой истории как тут, то тогда было бы понятно как переманивать программистов с других языков программирования.
Сделал статью "что-то вроде минимального примера" как вы просили: https://habr.com/ru/articles/978216/
Пойдёт?
вроде ничего специально не обфусцировал и просто выложил почти все свои исходники почти всех проектов(уже много лет назад), сейчас просто решил написать к ним статьи/документацию и пошарить на публику, вдруг какая-то толковая аудитория увидит/оценит/присоединится/поможет.
я исхожу из того, что вероятность найти полезных людей через открытую публикацию выше, чем риск пострадать от тех, кто просто хочет что-то утащить на халяву.
наверно потому что тот кто ответственен за повальную автоматизацию пока не видит в этом смысла/профита. да и зачем спешить? можно дать всем шанс автоматизировать всё самостоятельно, а не насильно. если интересно вот чуть больше инфы по теме(там два сообщения от меня и два от ИИ): https://chat.deepseek.com/share/hexvsm55d4xueez6mh
ИИ подсказывает что вы хотите узнать зачем вам вообще мигрировать типы, если можно описывать всё через таблицы и каждый раз собирать сцену заново? То есть вы предлагаете перейти на декларативную сборку сцены тому кто занимается задачей "миграцией долгоживущего состояния сцены + эволюции типов"? Если так то спасибо за идею, но мне мой подход больше нравится. почему/зачем я так делаю/сделал? - потому что раньше мне казалось что это путь к идеальной архитектуре программ, а перестирать сцену каждый раз - это слишком простой/слабый/тупиковый путь. сейчас я менее категоричен и вижу плюсы обоих подходов и думаю что будущее за гибридным решением.
попросил ИИ перевести на понятный мне язык, вот его цитата:
интерпретация от ИИ:
вот что я думаю читая это:
что бы я сделал если бы нашёл кого-то кто про финансирует open-source разработку? - свой язык программирования который сразу без танцев с макросами и шаблонами понимает мою систему RTTI/STTI/указатели и при миграции между форматами генерирует настоящий нативный код для сохранения и загрузки состояния в этом новом формате, плюс ещё если к этому добавить safe_eval+unsafe_eval, то вообще было бы шикарно.
мы здесь не сериализуем некоторые вещи связанные с выполнением программы, а именно:
не сохраняем стек вызовов
не сохраняем PC / позицию выполнения
не трогаем низкоуровневые детали вроде сетевых или GPU-состояний
мы тут сериализуем почти всё состояние данных, включая ссылки и типы, чтобы:
обновлять бинарь
мигрировать структуры
продолжать работу без VM
VM/JIT решают другую задачу - управление кодом, а не миграцию данных между версиями типов.
Ну чистая правда, даже придраться не к чему. Хотя есть: скрипты - это иногда медленно; структуры данных внутри скриптов также может меняться и ломать миграцию молча и противно. Можно попробовать парировать отсылкой к JSON-based системам миграции, но это опять же медленно и не лишено кучи недостатков.
100% правда. я так поступил из-за своего неумения проектировать программы. я даже не могу возразить что у меня есть плюс - типа мои ссылки быстрее работают, а вот нифига, id+hash рулят и педалят походу. Всё что меня спасает - это отсутствие коллизии хэшей вообще.
Используется при миграции между форматами.
ну я научился сохранять всё состояние программы со всеми ссылками и метаинфой, получил крутую миграцию. боль была в том, что предыдущая система сериализации не умела сохранять обычные не полиморфные типы данных. А это очень полезно для работы по сети, т.к там требуется компактность и скорость. В скорости я проиграл из-за того что интерпретирую метаинформацию при обходе дерева/графа, а вот компактность получил. Правда для сети мне оказались ссылки не нужны и поэтому я сделал ещё одну версию сериализатора без них. И она победила из-за своей скорости компиляции.
ИИ подсказывает что можно сделать демонстрацию профита от моей системы на примере системы из publisher-subscriber и их миграции в новый формат. Попробую сделать. Спасибо за то что навели на хорошую идею примера!
Там даже в README прямым текстом:
POST++ — это persistent object store на mmap, а не сериализация с миграциями.
Он предполагает стабильный layout, адреса и не поддерживает автоматическое изменение типов.
В моей задаче ключевыми были самоописание формата и обновление бинарника без потери данных, поэтому подход принципиально другой.
текстовый формат у меня чисто для отладки
виртуальная машина не решает проблемы миграции данных между разными(старой и усовершенствованной) системами типов, но зато позволяет менять код что очень круто, правда, как вы верно заметили, ценой замедления программы в 10-50 раз, что для меня не приемлемо.
Да, я хочу знать всё в своих программах :)