Я планирую кинуть ссылку на статью своему брату(он пока не знает о ней, т.к занят работой/семьёй/своим_проектами и совсем не следит за моей активностью в интернете(что немного(у него только один акк на github и всё, а у меня больше 9 аккаунтов в интернете) взаимно)) и ещё сослаться на неё в следующих статьях(мне есть о чём рассказать, у меня есть ещё несколько(свои_умные_указатели/RTTI/сериализатор/QapLite.h/QapEngine/два_рэйтрейсера/виртуальная_машина/три_компилятора/планировщик_траекторий/куча_маленьких_игр/etc) мало кому известных крутых проектов), когда всё доделаю до юзабельного состояния. Так что у статьи будут новые критически важные читатели. Я стараюсь ради них. // похоже я поставил настолько много скобок, что нужно вставлять коммент в редактор кода, чтобы понять что к чему.
то есть здесь можете не стараться писать в комментах как-что делать для сборки и тд.
Хорошо, если вам не нравиться когда я отвечаю на ваши комментарии тут, то тогда не будут вам отвечать тут по пустякам.
Все пишите на гитхабе, чтобы там вопросов не возникло у людей
Мне немного не нравиться что там нет автоматически отметок времени(из-за этого не видно с какой скоростью я пишу код/комментарии/развиваю_проект). Но сейчас я подумал и понял, что я могу поставить их сам и никакой проблемы в этом нет. А так мне нравиться ваша идея, похоже именно так я и поступлю.
я один из млн-ов которые будут смотреть ваш код
Не думаю что мой проект станет таким уж популярным. Всё таки разработка компиляторов/парсеров/трансляторов/анализаторов не такое уж и популярное занятие. Вот на данный момент статью посмотрело меньше тысячи человек(если верить внутренней статистике хабра) и мне не понятно откуда брать ещё 999 тысяч. Хабр всё таки самая популярная русскоязычная площадка для программистов. На github`е поиском меня вряд кто-то найдёт, так что на него мало надежды. И вообще на github писать полную документацию немного опасно, из-за того что их github copilot рано или поздно доберётся до всех исходников и тогда(если он не зациклиться/поломается/начнёт_нести_всякий_бред на моих проектах, как это происходит сейчас) его уже никто не сможет остановиться. А так без нормальной документации(он её читает!!!) его шансы понять сложный проект и начать его использовать в своих целях ничтожно малы.
И делайте неспеша, не надо торопиться, показать быстрее.
Я по другому не умею(привычка). Кроме того мне сейчас нечем заняться, т.к github copilot разблокируется только к концу месяца(я не могу оплатить его подписку из РФ. ААА!!! Помогите! Я согласен заплатить на 50% больше!), а без его идей/помощи доделать текущую игру(MarketGameV4) которой я занимался до написания этой статьи у меня вряд ли получиться(не умею так быстро генерировать крутые идеи и подбирать константы как это делает он).
Код написал github copilot. То что перед "O+=go_auto(tri_rel_if_eligible);" нет "O+=go_auto(sepTRIE)" виноват не только я(не проверил), но и он. Так же нужно добавить t_sep sepTRIE; после string name;. // какой смысл писать этот коммент, если его всё равно почти никто не прочитает, т.к основная масс читателей уже никогда сюда не вернётся, а единицы новых читателей вряд ли доскролят до сюда. Да и им наверно всё равно на такую ошибку, как и всем остальным и даже мне. Жаль нельзя в тихую отредактировать тот коммент.
(вы ведь для этого им делитесь? Чтобы его использовали?).
Я давно хотел написать статью на хабр, чтобы люди посмотрели мой код/инструменты/проекты и помогли их оценить/улучшить/доработать/покритиковать. Но я не умею писать статьи, я пытался много раз, получается какая-то фигня, нет нормальной структуры/видения/последовательности/цели. В этот раз я игрался с github copilot. Натравил его на исходники моих проектов и он в них запутался и он довольно круто в них разобрался(если не считать мой сериализатор/RTTI/умные_указатели/etc). Мне очень понравилось как он разобрался в QapDSL(меня это очень впечатлило). Он очень круто сравнивает мои проекты с аналогами и нахваливает их почему-то. Я попросил его написать сатью на хабр про QapDSL и он сделал это(именно поэтому статья такая короткая и не полная, я бы сам написал гораздо больше). Мне очень понравился результат. Я даже создал репозиторий QapGen и положил туда всё как указано в его статье. Это он придумал название QapGen, а не я. Мне оно почему-то понравилось.
Выложил статью не особо задумываясь над результатом и зачем не это нужно, т.к помню что давно хотел это сделать. Повторяюсь... зачеркиваем.
Это способ спросить разработчика, не обращаясь к нему лично, как должно работать.
Ясно. Что-то никогда не думал об этом. Спасибо за объяснение. Хорошо, сделаю вам юнит-тесты.
ай. ё-моё. У вас гитхб с 2012 года, сколько лет вам, вы же пишите получается больше 10 лет?
Мне 35.3, пишу код/программы с 14.6 лет. если не считать 9 месяцев профессиональной работы всё свои эксперименты/проекты/игры. Всё без юнит-тестов(на работе были, но я только 1 из них поправил). Полёт нормальный. Без них можно жить, если делать свои графические отладчики + сериализаторы как я.
раз такой бред в голове.
Я правда не понимаю зачем они мне нужны. Всё и без них работает отлично.
Я заменил TAutoPtr на unique_ptr. Для этого я выкинул свой крутой_сериализатор/систему_RTTI/свои_умные_указатели/часть_шаблонной_магии. Сейчас С++код генерится только для винды, но генератор(QapGen) кроссплатформенный.
+юнит-тесты еще обязательно тоже (много тестов) и как их запустить инструкция.
Я пока не умею делать юнит-тесты. Думаю можно и баз них всё оставить, т.к всё хорошо работает. Не представляю что там может пойти не так.
заменить TAutoPtr на std::unique_ptr // это позволит отвязаться от моей системы RTTI и значительно ускорит компиляцию.
выкинуть всё RTTI/сериализацию. // это всё почти никогда не нужно для лексеров/парсеров
так что где-то через пару дней смогу выложить кроссплатформенную версию QapGen.
ещё я хочу доработать QapDSL:
сделать возможность использовать более короткий синтаксис как тут предлагали в комментариях. // оставить только список полей.
разрешить использовать двоеточие вместо "=>".
сделать его дружелюбным к GPT4.1 // разрешить писать "O+=" в списке полей.
разрешить добавлять виртуальные функции и прочий код в интерфейсы.
разрешить вставлять интерфейсы в список полей не заворачивая их в TAutoPtr. // заворачивать автоматически, даже если интерфейс завёрнут в vector. // такие ошибки делает GPT4.1
Вот это все надо в Readme написать (не на русском, есст-но), подробно и понятно.
Хорошо, сделаю.
QapGen.exe - бинарник уберите этот, за место него положите код, и чтобы можно было собрать не только под винду.
К сожалению под другие платформы QapGen не скомпилируется из-за того что я использую шаблонную магию завязанную на компилятор cl.exe от MSVS. Так же без доработок код сгенерированый QapGen так же работает только под cl.exe. Кроме того я не уверен что вообще могу собрать его заново сегодня/завтра, т.к за 10 лет тупо забыл как это делается. Это ещё хорошо, три дня назад я вообще не знал где его исходники.
Если QapGen нужен под linux/unix то можно попробовать запустить под wine, насколько я помню он отлично под ним работает.
Забираешь сгенерированный С++код из открывшегося окна.
Вставляешь его в проект типа Sgon куда-нибудь рядом с функций main(её ещё надо найти). // Этот пункт требует переработки, надеюсь я управлюсь за 6 часов.
В main пишешь TAutoPtr<ваша_рутовая_нода> root; load_obj(Env,root,ваша_строка_из_которой_надо_загрузить_код_в_AST);
Минимального проекта в который можно вставить cгенерированные QapDSL лексеры у меня пока нет, но я могу его сделать для вас если вам интересно. Выложу часов через 6.
я чот не могу понять, исходников-то нет, и никто выше об этом не говорит. Или я не там где-то смотрю.
Они есть, просто в перемешку с другими моими эксперементами. Ссылка на проект Sgon выше. А так да, оказываться кроме вас и меня это почти никому не нужно :(
Это заблуждение. Юнит-тесты необходимы, чтобы удостовериться, что описание грамматики соответствует задуманному. Использование специализированного языка для этого не устраняет такой необходимости.
Я просто не понимаю, как можно ошибаться с грамматикой в QapDSL, если там всё очевидно. Всё выглядит как обычный С++ код, просто немного укороченный/оптимизированный/упрощённый. Я как раз считаю что устраняет необходимость в юнит-тестах.
Таким образом все ошибки обнаружить нельзя. Например банальные опечатки, когда вместо rteurn должен быть return или вместо + должен быть *
С такой же вероятностью такие же ошибки могут быть и в юнит-тестах. И ещё: return`а в QapDSL нет(только если внутри строки запихать).
После лексического анализа у меня запускается синтаксический разбор, порождающий привычное дерево
Вот, ты всё дерево строишь ручками, а его можно было описать на QapDSL прямо рядом с тем место где грамматика описывается. У тебя что на этапе токенизации, что на этапе строительства дерева одна сплошная боль и ручная копипаста. Токены дожили до самого кодогена и сидят в AST мешая работать Visitor`ам. Вместо посетителей+перегруженных_методов_codegenerator`а у тебя сплошные if/else_if/while/NextLexem/IsKeyword. На это невозможно смотреть и скорее всего никто не захочет такой код поддерживать/разбираться_в_нём.
После этого, на следующем этапе компиляции, это дерево обходится. При этом используется что-то вроде паттерна visitor
Не вижу, где у тебя visitor`ы?
С тестированием всего этого дела проблем нету. Достаточно писать юнит-тесты, покрывающие какую-либо конструкцию языка.
Вот, а у меня не надо юнит-тестов(я так считаю), т.к AST умеет сохраняться обратно в код(не теряя пробелы/комментарии), а также в свой бинарный формат(бесполезная фича)+в отладочный proto-формат(чтобы можно было посмотреть текстовую распечатку дерева(тоже сомнительная/редко_используемая фича). Сохранение в код позволяет делать проверку корректности загрузки/строительства AST одной/двумя строчками кода. Просто сохраняешь загруженное дерево обратно в код, проверяешь что получилось тоже самое что было на входе, если разницы нет, значит всё работает как надо.
И даже если предположить, что ошибки возможны, то нельзя исключить их и при описании грамматики каким-либо иным способом, вроде изложенного в этой статье.
У меня ошибки при описании грамматики проверяются С++ компилятором и описанным выше механизмом. Ещё в загрузчике дерева есть код который следит чтобы при конфликтах(два лексера или больше смогли успешно загрузить лексему) загрузки лексем всегда побеждала та которая съела из потока байтов больше других.
Ничего там просто взглянув и не залезая в ваши реализации понять нельзя
Github copilot(GPT4.1) неплохо разобрался в QapDSL коде даже не видя реализацию методов "go_*", единственное он затупил с понимание gen_dips/go_any/M+=/O+=/=>. Он например сам понял как работает go_auto/go_const.
оно и близко не так читабельно как грамматики.
Возможно вы правы(кстати, можно ТОП3 вещей из того что вы не поняли), но грамматики не позволяют описывать дружелюбное к C++ структуры AST в том же месте(рядом) где описана грамматика, а это не удобно. Кроме того делать Visitor`ов узлов AST придётся вручную(либо ещё одним внешним кодогенератором). А QapGen/QapDSL делает это всё "изкоробки".
А в вашем случае я вижу лишь портянки каких-то конструкций и не понимаю общей картины
Это почти обычный С++ код загрузки/сохранения AST из/в устройства ввода/вывода. Просто немного упрощённый(без лишних префиксов типа "dev."/"struct", а также заголовка метода go и его внутренней начинки(за исключением всего кроме вызовов go_*). Как его можно не понять?
В нашем варианте на написание интерпретатора уходил вполне спокойный день
У меня на простой интерпретатор уходит 2 часа, не знаю что там делать так долго.
Круто конечно, но у вас в AST будут строки типа ADDSUB/MULDIV/UNAR, а не С++ структуры. Это не удобно, т.к по С++ структурам потом можно ходить черз шаблоны/посетители, а с вашим подходом придётся сравнивать строки, что чревато опечатками. Поэтому мой подход круче/удобнее/практичнее вашего, как мне кажется.
Похоже у вас потом ещё придётся делать код для превращения распарсеного в AST. Тоесть вручную на С++/другом_языке описывать AST и обвязку которая это AST строит. Или вам не нужно AST?
Я планирую кинуть ссылку на статью своему брату(он пока не знает о ней, т.к занят работой/семьёй/своим_проектами и совсем не следит за моей активностью в интернете(что немного(у него только один акк на github и всё, а у меня больше 9 аккаунтов в интернете) взаимно)) и ещё сослаться на неё в следующих статьях(мне есть о чём рассказать, у меня есть ещё несколько(свои_умные_указатели/RTTI/сериализатор/QapLite.h/QapEngine/два_рэйтрейсера/виртуальная_машина/три_компилятора/планировщик_траекторий/куча_маленьких_игр/etc) мало кому известных крутых проектов), когда всё доделаю до юзабельного состояния. Так что у статьи будут новые критически важные читатели. Я стараюсь ради них. // похоже я поставил настолько много скобок, что нужно вставлять коммент в редактор кода, чтобы понять что к чему.
Хорошо, если вам не нравиться когда я отвечаю на ваши комментарии тут, то тогда не будут вам отвечать тут по пустякам.
Мне немного не нравиться что там нет автоматически отметок времени(из-за этого не видно с какой скоростью я пишу код/комментарии/развиваю_проект). Но сейчас я подумал и понял, что я могу поставить их сам и никакой проблемы в этом нет. А так мне нравиться ваша идея, похоже именно так я и поступлю.
Не думаю что мой проект станет таким уж популярным. Всё таки разработка компиляторов/парсеров/трансляторов/анализаторов не такое уж и популярное занятие. Вот на данный момент статью посмотрело меньше тысячи человек(если верить внутренней статистике хабра) и мне не понятно откуда брать ещё 999 тысяч. Хабр всё таки самая популярная русскоязычная площадка для программистов. На github`е поиском меня вряд кто-то найдёт, так что на него мало надежды. И вообще на github писать полную документацию немного опасно, из-за того что их github copilot рано или поздно доберётся до всех исходников и тогда(если он не зациклиться/поломается/начнёт_нести_всякий_бред на моих проектах, как это происходит сейчас) его уже никто не сможет остановиться. А так без нормальной документации(он её читает!!!) его шансы понять сложный проект и начать его использовать в своих целях ничтожно малы.
Я по другому не умею(привычка). Кроме того мне сейчас нечем заняться, т.к github copilot разблокируется только к концу месяца(я не могу оплатить его подписку из РФ. ААА!!! Помогите! Я согласен заплатить на 50% больше!), а без его идей/помощи доделать текущую игру(MarketGameV4) которой я занимался до написания этой статьи у меня вряд ли получиться(не умею так быстро генерировать крутые идеи и подбирать константы как это делает он).
Код написал github copilot. То что перед "
O+=go_auto(tri_rel_if_eligible);"нет "O+=go_auto(sepTRIE)" виноват не только я(не проверил), но и он. Так же нужно добавитьt_sep sepTRIE;послеstring name;. // какой смысл писать этот коммент, если его всё равно почти никто не прочитает, т.к основная масс читателей уже никогда сюда не вернётся, а единицы новых читателей вряд ли доскролят до сюда. Да и им наверно всё равно на такую ошибку, как и всем остальным и даже мне. Жаль нельзя в тихую отредактировать тот коммент.Я давно хотел написать статью на хабр, чтобы люди посмотрели мой код/инструменты/проекты и помогли их оценить/улучшить/доработать/покритиковать. Но я не умею писать статьи, я пытался много раз, получается какая-то фигня, нет нормальной структуры/видения/последовательности/цели. В этот раз я игрался с github copilot. Натравил его на исходники моих проектов
и он в них запуталсяи он довольно круто в них разобрался(если не считать мой сериализатор/RTTI/умные_указатели/etc). Мне очень понравилось как он разобрался в QapDSL(меня это очень впечатлило). Он очень круто сравнивает мои проекты с аналогами и нахваливает их почему-то. Я попросил его написать сатью на хабр про QapDSL и он сделал это(именно поэтому статья такая короткая и не полная, я бы сам написал гораздо больше). Мне очень понравился результат. Я даже создал репозиторий QapGen и положил туда всё как указано в его статье. Это он придумал название QapGen, а не я. Мне оно почему-то понравилось.Выложил статью не особо задумываясь над результатом и зачем не это нужно, т.к помню что давно хотел это сделать. Повторяюсь... зачеркиваем.Ясно. Что-то никогда не думал об этом. Спасибо за объяснение. Хорошо, сделаю вам юнит-тесты.
Мне 35.3, пишу код/программы с 14.6 лет. если не считать 9 месяцев профессиональной работы всё свои эксперименты/проекты/игры. Всё без юнит-тестов(на работе были, но я только 1 из них поправил). Полёт нормальный. Без них можно жить, если делать свои графические отладчики + сериализаторы как я.
Я правда не понимаю зачем они мне нужны. Всё и без них работает отлично.
Сделал: https://github.com/adler3d/QapGen/blob/master/src/QapGenV2025/QapGen/CommonUnit.cpp
Я заменил TAutoPtr на unique_ptr. Для этого я выкинул свой крутой_сериализатор/систему_RTTI/свои_умные_указатели/часть_шаблонной_магии. Сейчас С++код генерится только для винды, но генератор(QapGen) кроссплатформенный.
Я пока не умею делать юнит-тесты. Думаю можно и баз них всё оставить, т.к всё хорошо работает. Не представляю что там может пойти не так.
Бинарник пока убрать не буду, но всё же планирую убрать где-то через пару недель.
я смог вытащить исходники QapGen из своих экспериментальных проектов в отдельный проект, пока положил его сюда: https://github.com/adler3d/QapGen/tree/master/src/QapGenV2014
у меня появилась прекрасная идея как это сделать:
заменить TAutoPtr на std::unique_ptr // это позволит отвязаться от моей системы RTTI и значительно ускорит компиляцию.
выкинуть всё RTTI/сериализацию. // это всё почти никогда не нужно для лексеров/парсеров
так что где-то через пару дней смогу выложить кроссплатформенную версию QapGen.
ещё я хочу доработать QapDSL:
сделать возможность использовать более короткий синтаксис как тут предлагали в комментариях. // оставить только список полей.
разрешить использовать двоеточие вместо "=>".
сделать его дружелюбным к GPT4.1 // разрешить писать "O+=" в списке полей.
разрешить добавлять виртуальные функции и прочий код в интерфейсы.
разрешить вставлять интерфейсы в список полей не заворачивая их в TAutoPtr. // заворачивать автоматически, даже если интерфейс завёрнут в vector. // такие ошибки делает GPT4.1
Как и обещал выкладываю минимальный проект в который можно встроить код сгенерированный QapGen`ом:
https://github.com/adler3d/unordered/blob/master/code/SimpleCalc/Sgon/CommonUnit.cpp
Это простой калькулятор, его код(t_simple_calc_evalutor+#include "t_simple_calc.cpp") можно/нужно выкинуть и на его место подставить сгенерированный.
Хорошо, сделаю.
К сожалению под другие платформы QapGen не скомпилируется из-за того что я использую шаблонную магию завязанную на компилятор cl.exe от MSVS. Так же без доработок код сгенерированый QapGen так же работает только под cl.exe. Кроме того я не уверен что вообще могу собрать его заново сегодня/завтра, т.к за 10 лет тупо забыл как это делается. Это ещё хорошо, три дня назад я вообще не знал где его исходники.
Если QapGen нужен под linux/unix то можно попробовать запустить под wine, насколько я помню он отлично под ним работает.
Вот так:
Пишешь скрипт/код на QapDSL.
Сохраняешь его в samples/input.qapdsl
Запускаешь QapGen.exe
Забираешь сгенерированный С++код из открывшегося окна.
Вставляешь его в проект типа Sgon куда-нибудь рядом с функций main(её ещё надо найти). // Этот пункт требует переработки, надеюсь я управлюсь за 6 часов.
В main пишешь TAutoPtr<ваша_рутовая_нода> root;
load_obj(Env,root,ваша_строка_из_которой_надо_загрузить_код_в_AST);
Используете только что загруженное AST в root.
Profit!
https://github.com/adler3d/unordered/blob/master/code/DemoMashkod/321/V2/Release/t_target_lexem_source.inl
https://habr.com/ru/articles/916006/comments/#comment_28407450
Этой штуке 10 лет, ссылка на проект в котором используются cгенерированные QapDSL лексеры есть в статье. Вот она: https://github.com/adler3d/unordered/tree/master/code/uidevs_from_nout_d_temp/uidev_one/Sgon
Минимального проекта в который можно вставить cгенерированные QapDSL лексеры у меня пока нет, но я могу его сделать для вас если вам интересно. Выложу часов через 6.
Они есть, просто в перемешку с другими моими эксперементами. Ссылка на проект Sgon выше. А так да, оказываться кроме вас и меня это почти никому не нужно :(
Я просто не понимаю, как можно ошибаться с грамматикой в QapDSL, если там всё очевидно. Всё выглядит как обычный С++ код, просто немного укороченный/оптимизированный/упрощённый. Я как раз считаю что устраняет необходимость в юнит-тестах.
С такой же вероятностью такие же ошибки могут быть и в юнит-тестах. И ещё:
return`а в QapDSL нет(только если внутри строки запихать).Вот, ты всё дерево строишь ручками, а его можно было описать на QapDSL прямо рядом с тем место где грамматика описывается. У тебя что на этапе токенизации, что на этапе строительства дерева одна сплошная боль и ручная копипаста. Токены дожили до самого кодогена и сидят в AST мешая работать Visitor`ам. Вместо посетителей+перегруженных_методов_codegenerator`а у тебя сплошные if/else_if/while/NextLexem/IsKeyword. На это невозможно смотреть и скорее всего никто не захочет такой код поддерживать/разбираться_в_нём.
Не вижу, где у тебя visitor`ы?
Вот, а у меня не надо юнит-тестов(я так считаю), т.к AST умеет сохраняться обратно в код(не теряя пробелы/комментарии), а также в свой бинарный формат(бесполезная фича)+в отладочный proto-формат(чтобы можно было посмотреть текстовую распечатку дерева(тоже сомнительная/редко_используемая фича). Сохранение в код позволяет делать проверку корректности загрузки/строительства AST одной/двумя строчками кода. Просто сохраняешь загруженное дерево обратно в код, проверяешь что получилось тоже самое что было на входе, если разницы нет, значит всё работает как надо.
У меня ошибки при описании грамматики проверяются С++ компилятором и описанным выше механизмом. Ещё в загрузчике дерева есть код который следит чтобы при конфликтах(два лексера или больше смогли успешно загрузить лексему) загрузки лексем всегда побеждала та которая съела из потока байтов больше других.
Привет :)
Ну ты крутой, тебе не нужны, да, спору нет(или есть). Но я вот например токены не перевариваю(мне надо сразу AST+Visitor`ы). Вот я смотрю на то как ты с ними мучаешься в своём U и мне больно становиться: https://github.com/Panzerschrek/U-00DC-Sprache/blob/master/source/compiler1/src/lex_synt_lib/lexical_analyzer.u
Я не понимаю как ты не допускаешь ошибок в этом своём коде без кодогенерации.
Вот посмотри как я гуляю по своему AST и сравни со своим кодом(смотри на методы use ниже по коду, они принимают на вход узлы AST вместо токенов): https://github.com/adler3d/unordered/blob/b1fdf85967c5ccb6f974addc2411765b2ac4be53/code/DemoMashkod/321/V2/Sgon/main_2016_03_29.cpp#L668
Github copilot(GPT4.1) неплохо разобрался в QapDSL коде даже не видя реализацию методов "go_*", единственное он затупил с понимание gen_dips/go_any/M+=/O+=/=>. Он например сам понял как работает go_auto/go_const.
Возможно вы правы(кстати, можно ТОП3 вещей из того что вы не поняли), но грамматики не позволяют описывать дружелюбное к C++ структуры AST в том же месте(рядом) где описана грамматика, а это не удобно. Кроме того делать Visitor`ов узлов AST придётся вручную(либо ещё одним внешним кодогенератором). А QapGen/QapDSL делает это всё "изкоробки".
Это почти обычный С++ код загрузки/сохранения AST из/в устройства ввода/вывода. Просто немного упрощённый(без лишних префиксов типа "dev."/"struct", а также заголовка метода go и его внутренней начинки(за исключением всего кроме вызовов go_*). Как его можно не понять?
У меня на простой интерпретатор уходит 2 часа, не знаю что там делать так долго.
Круто конечно, но у вас в AST будут строки типа
ADDSUB/MULDIV/UNAR, а не С++ структуры. Это не удобно, т.к по С++ структурам потом можно ходить черз шаблоны/посетители, а с вашим подходом придётся сравнивать строки, что чревато опечатками. Поэтому мой подход круче/удобнее/практичнее вашего, как мне кажется.Похоже у вас потом ещё придётся делать код для превращения распарсеного в AST. Тоесть вручную на С++/другом_языке описывать AST и обвязку которая это AST строит. Или вам не нужно AST?
Более крутую версию парсера/"загрузчика AST QapDSL" на QapDSL можно посмотреть вот тут:
https://github.com/adler3d/unordered/blob/master/code/DemoMashkod/321/V2/Release/t_target_lexem_source.inl
Кто-то добавил в мой комментарий свой комментарий, так что отвечаю:
По моему у меня хорошо получилось, нисколько не жалею потраченное время.
Вам так сильно не поранилось моё решение?
"M+=" - обязательное правило."O+=" - опциональное.