Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 09.09.20 20:49
Оценка: 2 (2) +1 -2
Здравствуйте!

Точнее — парсинг и построение AST

Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.
Маньяк Робокряк колесит по городу
Re: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 10:38
Оценка: 2 (2) +2
Здравствуйте, Marty, Вы писали:

M>Хочу понять, как таки это делать правильно и быстро.


Тебе очень не хватает хоть минимального понимания теории вопроса.

Синтаксический анализ формальных языков — очень хорошо исследованнаа область знаний. Тут надо просто взять хорошую книжку, и ее прочитать. И немного попрактиковаться. Написать самому несколько парсеров, без помощи lex/yacc, или их более современных аналогов, чтобы осознать, что вообще происходит.

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

Реально есть некоторый баланс между удобством синтаксического разбора и удобством использования языка человеком. Например, LISP очень удобно синтаксически разбирать, но пользоваться неудобно. C++ — пример неудачного во всех смыслах языка, и парсить тяжело, и писать/читать тяжело. Go, Pascal — легко парсится, легко читается. Ну и т.д.

Далее, AST — это способ внутреннего представления результата синтаксического анализа. Собственно, синтаксический анализ и AST — ортогональные в определенном смысле вещи. Можно представить себе вполне полезный парсер, который не строит AST. Например, если единственное назначение парсера — проверить синтаксис на отсутствие ошибок и подкрасить текст в разные цвета, AST не нужен. Но если с текстом предполагается делать более серьезную обработку, AST — удобная структура.

Здесь тоже имеется баланс между удобством содержательной обработки и удобством диагностики. Чтобы сделать кодогенерацию для языка типа C, достаточно разбить программу на операторы, а выражения — на операции и операнды, сгруппировав их по порядку вычисления с учетом приоритетов операций. Но чтобы правильно высказаться, когда у тебя в глубине выражения выявилась смысловая ошибка (скажем, типы операндов не сошлись), надо до самого последнего момента хранить информацию о том, что пришло из какого файла и из какой строки (а желательно и положение в строке). Необходимость сохранения этой информации усложняет структуру AST, но делает диагностику куда как более вменяемой.

Что до инструментов, типа lex/yacc. lex — штука простая и удобная. Что до yacc, с одной стороны, очень удобно писать грамматику в виде варианта нормальной формы Бэкуса-Наура, и горя себе не знать. С другой стороны, практически полезный парсер должен разумно себя вести, наткнувшись на синтаксическую ошибку. Скажем, пропустили закрывающую скобку — с формальной точки зрения, это невалидный текст, достаточно сказать "syntax error", и завершиться. Если продолжать, наивно написанный парсер на yacc потеряет синхронизацию с текстом, и выдаст тебе еще по ошибке на каждую строку. Хорошо написанный парсер пропустит кусок текста, восстановит синхронизацию и дальше будет выдавать только новые ошибки, а не кучу "наведенных". Как это сделать — это искусство, а не наука, универсального ответа тут, к сожалению, нет. Но для человека это очень удобно, поскольку выдает разумную диагностику. Если посмотреть, многие широко используемые компиляторы начинали с парсера, написанного на инструменте типа yacc, но потом в какой-то момент парсер переписывался руками.

По моему опыту, написать с нуля вменяемый парсер руками и на yacc'е требует сравнимых усилий. Но если на момент написания парсера синтаксис до конца не устаканился, и возможны изменения в языке, парсер на yacc'е проще поддерживать, внося небольшие изменения в язык.

Далее, кроме синтаксического анализа, есть еще и семантический (смысловой). Когда программист пытается засунуть строку в целочисленную переменную, или описать переменную несуществуещего типа, такие ошибки ловятся уже после синтаксического разбора (а в некоторых альтернативно одаренных языках программирования вообще во время исполнения). Но есть неудачные языки, типа того же C++, в которых синтаксический анализатор вынужден взаимодействовать с семантическим анализатором, чтобы понять, например, слово asshole в данном контексте, это вообще что — название типа, название функции, название метода класса или что-то еще. Создателям компиляторов таких языков не позавидуешь, их семантический анализатор должен уметь отвечать на вопросы, касающиеся еще недоразобранного до конца текста.

Теперь, всегда ли нам нужен вообще парсер? С задачей, типа раскраски кода программы во все цвета радуги, можно справиться без полного синтаксического анализа, и обычно так и делают (хотя иногда такой "парсер на регулярных выражениях" и ошибается, но в большинстве случаев он работает хорошо).

Что до кодогенерации. О ней имеет смысл говорить, если мы делаем компилятор из языка программирования, грубо говоря, в ассемблер. Это очень обширная тематика, и в этой области ведется очень много исследований прямо сейчас, и современное состояние этой "науки" существенно отличается от того, что было, скажем, всего несколько лет назад. В общем, тут надо читать серьезную литературу, и по большей части она существует в виде статей на английском языйе, а не фундаментальных книг.

Однако для DSL серьезная кодогенерация вряд ли применима. Задача DSL — породить код на каком-нибудь C/C++, и дальше пусть уж настоящий компилятор сам с ним разбирается. Общее представление о кодогенерации иметь при этом невредно, чтобы хоть понимать, какой код компилятор C/C++ сумеет "улучшить", а где он ничего не поймет, и скомпилирует самым наивным образом. Кстати, для просто писания на C/C++ тоже невредно иметь такое понимание.

В общем, читайте книги — они рулез (ц)
Re[3]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 11.09.20 01:08
Оценка: +4
Здравствуйте, Marty, Вы писали:

M>Хочу не согласиться. Но, может, это просто моя "ошибка выжившего". Обычно хватает тупых инишек. Иногда — древовидных, где вложенность определяется отступами.


Хватать то хватает. Но ты продолжаешь делать ту же ошибку. Экономя человекодни на разработке инструмента теряешь человекогоды на его использовании. Активно используемый DSL (а делать его имеет смысл только при активном использовании) на много порядков умножает любое, даже копеечное удобство.

НС>>На прочтение и освоение чего то вроде драконов нужно потратить пару недель один раз в жизни, коли уж с профильным образованием не срослось. После этого пугаться лексеров и парсеров не будешь.

M>Дракон — драгон бук, что ли? Читал. Про образование — это типа задеть хотел?

Нет. Просто не могу иначе объяснить проблему с элементарными вещами. Написать простейший LL парсер проще и быстрее, чем рукопашный непонятный парсер лопатить, а потом годами вылавливать из него баги.

M>Но есть вопросы.

M>1) Примеры удачных DSL? Где взять?

DSL на то и DSL, что они D. Про твой D я ничего тебе посоветовать не могу. Возможно VHDL будет неплохим примером.

M>2) Тесты — хм. На них нет времени.


Мне надо повторить тезис про технологический уровень?

M>3) Тесты — дампы AST как должно быть — руцами писать? У меня нет пары лет на вылизывание всего этого.


Откуда взялась пара лет? Я куда более сложные DSL, уровня SQL, за 3-4 месяца один писал. С тестами. А то что у тебя — я вообще пока не понял при чем тут DSL. Такой ерунды у меня в том числе в текущих проектах — тонны каждый спринт.

M>4) Вот пример
Автор: Marty
Дата: 10.09.20
исходника на моём языке. Он сейчас вполне всех устраивает. Если тебе не сложно, не мог бы ты коротенько написать, как бы ты сделал его разбор? Ну, и как можно улучшить сам язык


Зачем там знаки $ и #? Что в нем такого, чего нельзя описать на yaml или json примерно теми же усилиями? Зачем тут вообще DSL, если, за исключением разве импортов да typedef, это простейшая древовидная структура? Если основные потребители — те кто использует плюсы и шарп, то зачем было изобретать свой нестандартный синтаксис? ?#!rdlc в начале зачем? Чем отличается include от import?
Что касается улучшения — очень сложно тебе что то посоветовать не варясь в вашей предметной области и не понимая смысла написанного. Если совсем обще — я бы убрал весь визуальный мусор, все эти ненужные значки, ввел бы нормальный конец строки и отказался от бейсиковых слешей для переноса. Синтаксис взял бы стандартный сишный. Сделал бы язык попонятнее — какие то префиксы в импорте, которых ниже по тексту нет, какой то ro, какие то неймспейсы сами по себе не ясно к чему относящиеся. Куча underscores.
generator=cpp:struct как бы намекает, что вместе с целевой областью тут какая то мешанина инструкций для процессинга, зачем оно там? В той секции что капсами — куча повторяющихся слов.
<< это что? Распиновка? >> может там быть? Если нет, то ты зря направленную, да еще и двойную лексему использовал. Достаточно симметричного значка типа -. Почему там слева везде только 1? Там может быть что то другое? Часто?
$typedef u8 : bool. По смыслу — новый тип u8, идентичный bool. А судя по тому что ниже — наоборот. Я понимаю что моск С++ испорчен, но там хоть : нет и можно какую то извращенную логику натянуть. Но лучше не заставлять человека гадать. type bool = u8 любого, с любым бекграундом, в заблуждение не введет, в отличие от.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 10.09.20 20:28
Оценка: 2 (1) +2
Здравствуйте, Marty, Вы писали:

M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму".


Не помню такого. Но технологический уровень описанного, скажем так, не особо выше плинтуса. Особо неверно вот это:

Делайте тупой построчный разбор. В 90 процентов случаев этого достаточно для DSL


На прочтение и освоение чего то вроде драконов нужно потратить пару недель один раз в жизни, коли уж с профильным образованием не срослось. После этого пугаться лексеров и парсеров не будешь.
Теперь про создание DSL в частности и языков в общем.
Главный критерий языка — удобство его использования человеком. Непонимание этого — одна из самых частых ошибок неопытных изобретателей языков. Начинать его проектирование нужно не с подбора технологий и алгоритмов, а с описания на нем реальных кейсов и коридорного тестирования результатов. При этом нужно включать зануду по полной — любое сомнение или шероховатость должно подвергаться нещадному анализу. А поскольку у тебя в этот момент еще ничего не написано — не будет возникать посознательного нежелания кардинально все менять.
Когда ты этим позанимаешься определенный срок, хотя бы дней несколько — тебя начнет посещать дао. Ты немного по другому начнешь мыслить, не так как обычно при проектировании софта для решения определенных проблем.
В какой то момент твой язык в голове начнет превращаться во что то осязаемое и цельное. И именно здесь от тебя требуется по максимуму инженерный талант, то что отличает тебя от кучи сереньких кодеров. А так же хорошее знакомство с современными примерами удачных DSL, потому что некоторые красивые велосипеды не так то просто придумать с нуля.
Когда появится что то законченное — надо зафиксировать результат в любом понятном тебе виде.
Теперь можно написать ... нет, не код а тесты. Тесты для парсеров/компилеров обычно представляют собой коротенкий кусочек с одной фичей на исходном языке набор голдов, т.е. дампов промежуточных и конечных структур — разных стадий AST и конечного кода или исходников. Результат этого этапа — это самое ценное и сложное, что нужно сделать при разработке DSL.
Ну а дальше остается только реализовать это — написать парсер, генератор, компилятор, интерпретатор или что там тебе нужно. На этом этапе можно слегка подрихтовать грамматику, чтобы не создавать лишних сложностей, например чтобы запихнуть ее в LL(1). Пишешь ли ты руками или используешь генераторы лексеров/парсеров при этом — совершенно не принципиально. Разница в скорости реализации обычно десяток-другой человекодней.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 09.09.20 21:00
Оценка: +1 -2
M> не просто: "ты лошара неграмотная

Только Java, только Antlr
Re: Написание своего DSL
От: Мёртвый Даун Россия  
Дата: 10.09.20 08:35
Оценка: -1 :)
Здравствуйте, Marty, Вы писали:

Нафига в ЖЖ? Ты бы еще в контактике запилил.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re[3]: Написание своего DSL
От: Мёртвый Даун Россия  
Дата: 10.09.20 08:36
Оценка: +1 -1
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Классический учебник по теме — https://www.springer.com/gp/book/9783642148453


Отбой, она платная. Я люблю только всё на безвозмедной основе.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re[8]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 11:52
Оценка: +1 -1
Здравствуйте, Ночной Смотрящий, Вы писали:

N>>А вот не понять, что разговор ушёл на более общую тему — вот это точно неуместно.

НС>А, ну то есть было из разряда "у рыб шерсти нет ...". Сорри, думал раз ник не Serginio, то можно не сильно опасаться что собеседник на своей волне.

Достаточно всего лишь было прочитать моё сообщение и то, на которое я отвечал.

НС>>>И? Насколько эти фичи востребованны для лексического анализа DSL?

N>>Сильно зависит от того, какой DSL. Новые, да, лучше так не писать, но есть до чёрта всякого наследия.
НС>Так топик то про создание DSL, а не про написания парсера для готовых.

Так теперь уже ты не ограничиваешь только созданием DSL. Сказано же — для лексического анализа.

N>>>>Всё, что я в пару последних лет смотрел, этим не страдает — юникод это просто факт нижнего уровня

НС>>>Вопрос в том как устроен его анализ. Если внутри лексера не копаться то да, просто факт.
N>>Мне достаточно того, что лексер умеет определять
НС>Я именно это и написал. Я же писал про то как это внутри устроено и какие проблемы бывают при написании собственных лексеров.

Никакой конкретики, чем юникод тут мешает, пока не поступило. Если писал где-то ещё — давай ссылку, я как-то не веду досье на собеседников.

НС>>>И? Дальше то что? Оставаться на НКА и не строить ДКА, как большинство движков для регексов делают? Для парсеров языков это не очень хорошая стратегия часто.

N>>Не совсем понял связь. По-вашему ДКА предполагает построение полной таблицы символов для лукапа, то есть 256 при восьмибитке и 64K при 16-битке?
НС>Нет, это наивный подход, который плохо работает.

То есть конкретики по-прежнему нет. Oook...

N>>Ну взгляните тогда хотя бы на re2c, он делает ДКА и любой юникод принимает без проблем.

НС>Я смотрел, не переживай. И от того что там намного чаще натыкаешься на проблему экспоненциального роста количества состояний он не спасает.

Экспоненциальный-то откуда?

N>>>>Видимо, это проблема средств вокруг вас (C# и прочее, да?)

НС>>>Ну да, если аргументов нет то надо искать проблемы в собеседнике.
N>>Ещё не начинал.
НС>Именно это ты и сделал и продолжаешь в том же духе.

Ещё нет. Но скоро, похоже, придётся.
The God is real, unless declared integer.
Re[5]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.20 04:26
Оценка: +2
Здравствуйте, Михaил, Вы писали:

М>Случайно зашёл в дискуссию и, будучи не в теме, стало любопытно. Можно в двух словах, в каких случаях оптимально создание нового дсл? Почему-то казалось, что в большинстве случаев проще взять готовый язык (который большинству людей априори знаком), вроде python, lua, typescript/js, и на его основе городить скриптовый движок, чем изобретать новое «наречие».


Возьмём в качестве знаменитого примера SQL. Это уже заметно формализованный язык со своей логикой, но уже нормально, что непрограммистов пускают исполнять SQL-запросы напрямую через клиента типа SQL*Plus или из каких-нибудь экселевских таблиц. И пусть у нас есть:
1) select m.name as name, sum(s.amount) as total from managers m, sells s where m.id = s.manager_id group by m.id order by total desc
да, формализованно и требует понимания логики базы, но уже не программа по выборке;
2) какое-нибудь
var m = db.table("managers");
var s = db.table("sells");
var query = db.newQueryFromInnerJoin(m, s, onEqual(m.field("id"), s.field("manager_id")));
query
  .sortBy(m, "id")
  .addOutputColumn("name", m, "name")
  .addOutputColumn("total", groupFunction("sum", s, "amount", groupBy: name))
  .sortBy("total", -1);
result = query.execute();

3) то же уже в виде операций доступа к конкретным таблицам (даже если план исполнения запроса однозначен), облом расписывать... попробуйте сами представить себе это, если таблицы сделаны в виде, например, map (C++) с отдельными индексами и структурами полей.

В варианте 2 ещё более-менее понятно (а можно было вообще LINQ вспомнить, но я с ним не работал), но уже опасность — так как это исполняемый код, как защититься от вредных воздействий автора запроса? Исполнять всё в специальной песочнице? Не всегда возможно, почти всегда дорого.

А если допускать к конкретному API — вот мы завтра решили, что нам вместо последовательности addOutputColumn нужен отдельный объект шапки, который одновременно даёт ссылки на поля для упоминания в тексте (чтобы можно было один раз вместо всех этих m, "name" получать объект ссылки) — все должны переписывать свои запросы?
Ну и снова вопрос секьюрити.

При создании DSL крайне важным является не то, что язык может, а то, чего язык не даёт сделать, и как описываются определённые вещи. Писать юзеру на языке программирования может быть:
— неудобно, потому что ему нужно каждый раз преобразовывать свои мысли в другую форму, с которой он незнаком, а при чтении — и обратно. Причём его форма может быть даже не текстовой(!) — DSL может быть, например, графическим.
— страшно, потому что он будет бояться зацепить что-то не то и создать нежелательный побочный эффект. (а
админы системы будут бояться пускать его код даже в песочнице, потому что мало ли что напишет.)
— плохо при замене особенностей реализации (внутреннее API может меняться хоть каждый месяц, зачем юзерам
всё переписывать под него?)

Разумеется, при создании DSL что-то теряется — затраты человека (поддерживать внутренний язык), машины (его разбирать и переводить в свою логику, при компиляции или в рантайме), но это окупается целевым результатом.
The God is real, unless declared integer.
Re[4]: Написание своего DSL
От: alpha21264 СССР  
Дата: 11.09.20 10:19
Оценка: 3 (1)
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Здравствуйте, Эйнсток Файр, Вы писали:


ЭФ>>Классический учебник по теме — https://www.springer.com/gp/book/9783642148453


МД>Отбой, она платная. Я люблю только всё на безвозмедной основе.


Я нашёл полный pdf этой книжки. Если кому-то нужно, могу выслать.

Течёт вода Кубань-реки куда велят большевики.
Re: Написание своего DSL
От: alpha21264 СССР  
Дата: 09.09.20 21:18
Оценка: 2 (1)
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Точнее — парсинг и построение AST


M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.


Это очень зависит.
Нынешняя практика парсинга опирается на Хомского, дегенераивные грамматики и позиционные языки, похожие на английский.
Я в моей практике (не очень сложных парсеров) пришёл к противоположной методике.
Каждое слово языка имеет тэг. Первый символ (несколько символов) любой переменной — это тэг.
И этот тэг определяет в какой массив и какую структуру AST ты его записываешь.

Таким образом любой парсер пишется вот так:

   for( int i=0 ; i<n_Word ; i++ )
   {  switch( Word[i][0] )
      {
         case '$' : AllData.Array1[j1++]                  = func1( Word[i] ) ; break ;
         case '@' : AllData.Array2[j2++]                  = func2( Word[i] ) ; break ;
         case '&' : AllData.Array2[j2].Member[j_Member++] = func3( Word[i] ) ; break ;
      }
   }


Вместо [j_Mass1++] можешь push_back() писать.

И да, для этого надо иметь возможность самому создавать свой DSL, чтобы самому назначать тэги.

PS.
Вот тут один персонаж (еретик) рассказывает про подобную методику. Только он ещё "иероглифы" (это такие своеобразные тэги) делает:

https://youtu.be/LxMj6ZYfbpU?t=898

Течёт вода Кубань-реки куда велят большевики.
Отредактировано 09.09.2020 21:27 alpha21264 . Предыдущая версия .
Re[4]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.20 05:02
Оценка: 2 (1)
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, netch80, Вы писали:


N>>Регэкспы — давно не вкладываются в регулярные грамматики.


V>Регеспы POSIX в точности описывают регулярную грамматику.

V>Может ты имел ввиду расширенные варианты, типа https://ru.wikipedia.org/wiki/PCRE?

В первую очередь их, да. Но про POSIX ты неправ, или отстал. POSIX допускает так называемые back-references:

For example, the expression "^\(.*\)\1$" matches strings consisting of two adjacent appearances of the same substring


на регулярную грамматику ты такое не уложишь, это уже context dependent.

Там есть таракан, что по POSIX они допустимы только в basic regexps, но не extended — а расширения все делаются поверх extended (кроме vim с его спецификой), но это не отменяет их присутствия.

V>Да, в Перле регекспы расширили обратными ссылками и те перестали быть регулярными выражениями.

V>По-хорошему, термин тоже надо было изменить...

Не они первые начали. Термин, да, размылся.

N>>PEG используется каждым вторым.


V>Тю!

V>Когда-то область компиляторостроения и вообще парсинга была "необъезженной", по ней неплохо готовили специалистов, бо отрасль нуждалась.
V>С приходом XML, JSON, YAML и прочих структурированных форматов практическая надобность в большом кол-ве специалистов по парсерам иссякла.

V>Отсюда те частые наблюдения, что когда необученные программеры начинают лабать нисходящие парсеры на коленке, т.е. методом проб и ошибок, получается банальный PEG.


Момент, когда "отрасль нуждалась", я пропустил, видимо. Я наблюдаю, да, невысокий, но постоянный спрос и всё равно при этом решения на PEG занимают заметную нишу.

Может быть, как раз потому, что они естественно ложатся на мышление того, кто ещё не загнан правилами LL/LR на конкретные рельсы мышления и/или не понимает важности их ограничений (а, может, это одно и то же условие).

A>>>И этот тэг определяет в какой массив и какую структуру AST ты его записываешь.

N>>Есть такие языки, но в целом это неудобно.
V>В целом это сводит парсер по сложности примерно к хеш-таблице. ))

Увы, ещё нет. Посмотри на Perl
там теги типа $ — скаляр, @ — список, % — хэш, но "к хэш-таблице" его парсер несводим (не буду вдаваться в то, насколько несводим)
Ладно, на старый BASIC с его A! — целое, A$ — строка, A% — вещественное. Всё равно выражения надо парсить.

V>Первый Фортран не далеко от такого ушел (до введения типизации):

V>

V>переменные, имена которых начинаются с одной из шести букв I, J, K, L, M, N (например: IGREK5, LA, М, K2N3AB и т.д.), являются величинами целого типа, а с любой другой буквы (AL, X, DELTA и т.д.) — величинами вещественного типа.


Нет, это не "первый" Fortran. Это уже правила Fortran II.
Более того, в нём это были типы по умолчанию, и их можно было заменять явным определением типа конкретной переменной.

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

Но у раннего Фортрана интереснее даже не это, а фокус, как там решали проблему приоритетов.
Любое выражение обрамлялось (( )).
* и / заменялись на )*( и )/(, + и — — на ))+(( и ))-((.
Дальше логика работала только учётом скобок.
Такой себе древний самопальный аналог правил Пратта с приоритетами.
The God is real, unless declared integer.
Re[2]: Написание своего DSL
От: RonWilson Россия  
Дата: 10.09.20 08:55
Оценка: +1
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Здравствуйте, Marty, Вы писали:


МД>Нафига в ЖЖ? Ты бы еще в контактике запилил.


не, всё правильно, с таким:

А по факту — я наелся говна.


Но это так, не говно на самом деле.


Накушавшись говна с flex/bison, я потрогал ещё кучу разного.


там этому и место.
Re: Написание своего DSL
От: Рома Мик Россия http://romamik.com
Дата: 10.09.20 10:15
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.

Всегда писал разбор руками, методом рекурсивного спуска. Другие методы даже не пробовал. Ну крутил в руках всякие yacc и подобные, но не более. Обычно собственно разбор — это очень быстро по сравнению с остальной работой по использованию полученного AST.
Re[4]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 10.09.20 21:03
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Я его трогал, тогда была только джава.


Ты не перепутал язык, на котором он написан и его таргеты? Таргет для С++ там уже лет 20 точно есть.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.09.20 06:03
Оценка: +1
Здравствуйте, Marty, Вы писали:
M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.
Если честно, то ничего не понял. Больше похоже не на статью, а на тизер. Ну, типа как "экстреманльная евангелизация в фейсбуке" — пишем что-то типа "ANTLR говно, yacc говно, писать на yacc/bison — обмазаться говном", провоцируем дискуссию, в рамках которой ссылка на настоящую статью, приведённая в стартовом посте, всплывает в топ.

А так — непонятно примерно ничего. Объём текста большой, но нет никаких конкретных фактов, за которые бы можно было зацепиться взглядом или мозгом.
Зато есть куча путаницы. Типа — вот у нас парсинг, потом построение AST, потом генерация кода.
Тут же ремарка: "по факту про генераторы кода я ничего и не написал. Тут всё зависит от того, как вы спроектируете AST своей предметки."
И сразу же "Если генерить немного — просто пишу код генератора на плюсиках. "

Я уже запутался: кто что генерирует? Кто что написал или не написал?
Что значит "просто пишу код генератора на плюсиках"?
"код генератора" и "генератор кода" — это одно и то же, или наоборот?

Что значит "на плюсиках"? Упоминание о том, вы пишете на С++, уже было.
  Оффтоп
Для полноты картины стоило бы, конечно, упомянуть и о том, что писать инструменты по трансляции кода на плюсах — это боль.
Например потому, что примерно 90% любого транслятора — это манипуляции с деревьями, в процессе которых узлы трансформируются, удаляются, и добавляются. Отслеживать время жизни руками — устанешь пот со лба утирать.
Любой язык со сборкой мусора даст 100 очков вперёд.
Далее, обработка гетерогенного дерева — это либо паттерн матчинг, либо паттерн визитор. Визитор — многословное, непонятное, трудноотлаживаемое месиво.
Поэтому, например, писать инструменты по трансляции кода на жабе — это боль.

Любой язык с паттерн-матчингом и сборкой мусора в этом смысле заруливает язык без них в минуса.
Именно поэтому, кстати, так популярны инструментальные средства по построению компиляторов для С++ и прочего — рукопашная работа там это просто ужоснах.


Вроде бы из этого сумбурного текста следует, что вы хотите рассказать о том, как делать AST из потока лексем.
Вот в этот момент было бы неплохо порассуждать о том, как, по-вашему, должно быть устроено это AST, от чего зависит это устройство, и так далее. Привести примеры.
Потом уже можно (потенциально) обсуждать, как именно поток байтиков (или лексем) превращается в AST. Увы, ничего этого нету. Кроме советов "просто пишите код".
В конце вы почему-то перескакиваете на генерацию кода, и внезапно оказывается, что задача написания своего DSL решается вовсе без DSL, прямой генерацией.
Кто на ком стоял?

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

К примеру, у нас на ФИТ НГУ читают такой курс, как "Методы трансляции и компиляции программ". За 15 пар семинаров (это примерно 1 рабочая неделя) детишки от состояния "читаю java со словарём" переходят к состоянию "мы написали верифицирующий компилятор для аннотированных программ на модельном языке недетерминированного программирования". Очень рекомендую всем начинающим.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 10:47
Оценка: +1
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>А сейчас есть системы грамматик, покрывающие натуральные языки (со сложностью разбора O(N^6))

ЭФ>- вот это нынешняя практика.

Суда по поведению автоматических переводчиков, скорее этих систем грамматик нет, чем они есть.
Re[5]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 10:49
Оценка: :)
Здравствуйте, netch80, Вы писали:

N>Если смотреть на правила какого-нибудь C#, в каком случае > будет считаться знаком сравнения, а в каких — закрывающей скобкой шаблона, то это уже заметно напоминает естественные языки. А C++ так вообще превращается в один из них со своей зависимостью от контекста, который ещё не задан


Язык, на котором нельзя сказать обидную гадость, не может считаться естественным
Re[16]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 11:45
Оценка: :)
Здравствуйте, Ночной Смотрящий, Вы писали:

N>>Ну пусть не имеет. Откуда идея, что весь файл целиком должен представлять только то, что "имеет отношение к domain"?

НС>Потому что это упрощает чтение и понимание написанного.

Не вижу причин к такому выводу.
Кому-то крайне критично наличие шапки типа "Одобрено ГРУ ВАСХНИЛ" и без этого документ просто не воспринимается. На то он и домен.

N>>Обычно не окупается. И ещё и имеет тяжёлые проблемы с развитием языка.

НС>Ну вот и ответ тогда на заданный тобой вопрос.

Только он противоположен тому, что ты выдвигаешь.
The God is real, unless declared integer.
Re[5]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 15:02
Оценка: +1
Здравствуйте, Михaил, Вы писали:

М>Случайно зашёл в дискуссию и, будучи не в теме, стало любопытно. Можно в двух словах, в каких случаях оптимально создание нового дсл?


Когда приходится писать много однообразного кода, большая часть которого тупая копипаста. Причем для написания этого кода требуется хорошее знание не программирования, я предметной области. И когда у тебя есть бюджет на написание DSL.

М> Почему-то казалось, что в большинстве случаев проще взять готовый язык (который большинству людей априори знаком), вроде python, lua, typescript/js, и на его основе городить скриптовый движок, чем изобретать новое «наречие».


Не всегда проще. И для таких языков нельзя задавать ограничения, чего делать нельзя. DSL обычно ближе не к скриптам, а к конфигам. Собственно, DSL, как правило, это сложные конфиги и есть.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: scf  
Дата: 14.09.20 08:50
Оценка: :)
Здравствуйте, Marty, Вы писали:

M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.


Увидил топик, не смог пройти мимо. Итак, по моему опыту:

Самый простой и полезный DSL — это DSL кодом. Т.е. DSL представляет из себя вызовы некоторых, написанных заранее функций, реализация которых собирает в памяти структуру данных (тот же AST), которая дальше процессится какой-то логикой и генератором

Для текстового DSL я применяю самописные рекурсивные нисходящие парсеры https://en.wikipedia.org/wiki/Recursive_descent_parser
Очень рекомендую, эта техника написания парсеров проста в освоении и исключительно полезна.

Простые генераторы отлично пишутся кодом вперемешку со строками, для более сложных нужен любимый template engine, пачка шаблонов и обязательно отдельная модель для использования в этих шаблонах.
Re: Написание своего DSL
От: alexanderfedin США http://alexander-fedin.pixels.com/
Дата: 23.10.20 21:00
Оценка: +1
Здравствуйте, Marty, Вы писали:
M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.
Я юзал Coco/R + .NET Code DOM
Respectfully,
Alexander Fedin.
Re[2]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 09.09.20 21:02
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

M>> не просто: "ты лошара неграмотная


ЭФ>Только Java, только Antlr


Он умеет строить AST за тебя? Плюшечный построить сможет?
Маньяк Робокряк колесит по городу
Re[3]: Написание своего DSL
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 09.09.20 21:04
Оценка:
M> Он умеет строить AST за тебя?
https://stackoverflow.com/questions/29971097/how-to-create-ast-with-antlr4

M> Плюшечный построить сможет?

https://github.com/antlr/antlr4/blob/master/doc/cpp-target.md
Отредактировано 09.09.2020 21:06 Эйнсток Файр . Предыдущая версия . Еще …
Отредактировано 09.09.2020 21:05 Эйнсток Файр . Предыдущая версия .
Re[2]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 09.09.20 22:33
Оценка:
Здравствуйте, alpha21264, Вы писали:


A>Это очень зависит.

A>Нынешняя практика парсинга опирается на Хомского, дегенераивные грамматики и позиционные языки, похожие на английский.

Блин, старика Хомского не читал. А если и читал, то забыл


A>Я в моей практике (не очень сложных парсеров) пришёл к противоположной методике.

A>Каждое слово языка имеет тэг. Первый символ (несколько символов) любой переменной — это тэг.

Когда свой язык — ещё ладно, можно.
Когда чужой — уже никак.

Мне интересно, есть ли та волшебная пуля, которая за меня построит AST, опиши я язык в BNF или ещё каком виде.

Или вся эта шляпа с LL(X)/LR(X)б контекстно свободными/зависимыми грамматиками — просто псевдонаучно обоснованный развод для лохов, чтобы платили за то, что им вливают в уши?

Баксами, к слову, я тоже пользуюсь

  Пример моего DSL
#!rdlc

$typedef u8 : bool

$include "sample_types.rdl"


$device "battery" - Батарейка

        $import "Motherboard" from <volk.rdl> as VolkMotherboard prefix vlk_

    $namespace rw

        power_off         : u8
        user_output_state : u8

    ro:
        
        $group "Напряжения"
        voltage_millivolts\
         : u16 \
         - "общее напряжение на выходе"
        cell_1_millivolts  : u16
        cell_2_millivolts  : u16
        cell_3_millivolts  : u16
        cell_4_millivolts  : u16 - "на самом деле этой ячейки тут нет, она оставлена для совместимости номеров регистров с другими батарейками"
        
        charge_percent                     : u8
        run_time_to_empty_minutes_u16      : u16 - "предполагаемое время работы на основе текущих данных"
        average_time_to_empty_minutes_u16  : u16 - "предполагаемое время работы на основе среднего тока"
        average_time_to_full_minutes_u16   : u16 - "предполагаемое время до полной зарядки"

        safety_status_u32                 : u32 - "битовое поле, см. SafetyStatusBits ниже"
        pf_status_u32                     : u32 - "битовое поле, см. PfStatusBits ниже"
                                          
        temperature_decikelvin_u16        : u16 - "это 0.1 Кельвина"
                                          
        current_milliamp_s16              : s16
                                          
        cycle_count_u16                   : u16
        state_of_health_percent           : u8
                                          
        operation_status_u32              : u32 - "битовое поле, см. OperationStatusBits ниже"
                                          
        is_voltage_ok                     : bool
                                          
        user_input_state                  : bool
        custom_error                      : u8 - "битовое поле, см. CustomErrorBits ниже"

        $type [generator=cpp:struct] SafetyStatusBits : u, 32 - "Биты внутреннего регистра Safety Status"
        
             CELL_UNDERVOLTAGE                    : 1 << 0  
             CELL_OVERVOLTAGE                     : 1 << 1  
             OVERCURRENT_DURING_CHARGE_1          : 1 << 2  
             OVERCURRENT_DURING_CHARGE_2          : 1 << 3  
             OVERCURRENT_DURING_DISCHARGE_1       : 1 << 4  
             OVERCURRENT_DURING_DISCHARGE_2       : 1 << 5  
             OVERLOAD_DURING_DISCHARGE            : 1 << 6  
             OVERLOAD_DURING_DISCHARGE_LATCH      : 1 << 7  
             SHORT_CIRCUIT_DURING_CHARGE          : 1 << 8  
             SHORT_CIRCUIT_DURING_CHARGE_LATCH    : 1 << 9  
             SHORT_CIRCUIT_DURING_DISCHARGE       : 1 << 10 
             SHORT_CIRCUIT_DURING_DISCHARGE_LATCH : 1 << 11 
             OVERTEMPERATURE_DURING_CHARGE        : 1 << 12 
             OVERTEMPERATURE_DURING_DISCHARGE     : 1 << 13 
             CELL_UNDERVOLTAGE_COMPENSATED        : 1 << 14 

             OVERTEMPERATURE_FET                  : 1 << 16 

             PRECHARGE_TIMEOUT                    : 1 << 18 

             CHARGE_TIMEOUT                       : 1 << 20 

             OVERCHARGE                           : 1 << 22 
             OVERCHARGING_CURRENT                 : 1 << 23 
             OVERCHARGING_VOLTAGE                 : 1 << 24 
             OVER_PRECHARGE_CURRENT               : 1 << 25 
             UNDERTEMPERATURE_DURING_CHARGE       : 1 << 26 
             UNDERTEMPERATURE_DURING_DISCHARGE    : 1 << 27
        
        $end_type

        safetyStatusBits : SafetyStatusBits - "Status"


Пример (рабочий) на моём DSL из последнего. DSL изначально был рождён как построчный парсер инишки, потом, по мере взросления, фичи добавлялись. Но не по науке, а как пришлось. Зато первая версия заработала уже через пару-тройку дней.

Тема зашла, коллеги пишут генераторы кода по моему AST'у. Но front я тяну сам. В рукопашную. А хочется описать BNF и какая-то тулза всё сделает за меня. AST, в том числе.


A>PS.

A>Вот тут один персонаж (еретик) рассказывает про подобную методику. Только он ещё "иероглифы" (это такие своеобразные тэги) делает:

A>https://youtu.be/LxMj6ZYfbpU?t=898


Спс, посмотрю
Маньяк Робокряк колесит по городу
Re[2]: Написание своего DSL
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 09.09.20 22:38
Оценка:
A> Нынешняя практика парсинга опирается на Хомского, дегенераивные грамматики и позиционные языки

Это знания, полученные тобой 30 лет назад, опираются ...

А сейчас есть системы грамматик, покрывающие натуральные языки (со сложностью разбора O(N^6))
— вот это нынешняя практика.

Классический учебник по теме — https://www.springer.com/gp/book/9783642148453
Re: Написание своего DSL
От: omgOnoz  
Дата: 10.09.20 07:55
Оценка:
Здравствуйте, Marty, Вы писали:

Я бы искал готовый инструмент
Re[3]: Написание своего DSL
От: alpha21264 СССР  
Дата: 10.09.20 10:24
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

A>> Нынешняя практика парсинга опирается на Хомского, дегенераивные грамматики и позиционные языки


ЭФ>Это знания, полученные тобой 30 лет назад, опираются ...


Я говорю на современную практику, которую используют программисты. lex/yacc, GCC и всё такое.

ЭФ>А сейчас есть системы грамматик, покрывающие натуральные языки (со сложностью разбора O(N^6))

ЭФ>- вот это нынешняя практика.

Я не знаю, что такое "сложность разбора натурального языка O(N^6)".
Вообще, цифра 6 в скобочках после O() приводит меня в ужас.
Это что, действительно полином шестой степени?! А в чём польза?

ЭФ>Классический учебник по теме — https://www.springer.com/gp/book/9783642148453


А что там такого? Покупать книжку за 50 долларов, чтобы убедиться, что там лажа я не буду.
Это лучше или хуже, чем вот это? Тут вся грамматика английского языка умещается на одной странице:

https://www.youtube.com/watch?v=lqL45eVcGIg

И напоминаю — мы обсуждаем DSL. Натуральные языки — это совершенно другая тема.

Течёт вода Кубань-реки куда велят большевики.
Re: Написание своего DSL
От: kov_serg Россия  
Дата: 10.09.20 13:06
Оценка:
Здравствуйте, Marty, Вы писали:

M>Запилил статейку на эту тему...

Вам не нужен DSL. Вам для кодогенерации нужен шаблонизатор и готовый скриптовый язык.
Из коробки в нормальных системах из коробки есть perl или доставляется php.
ps: лично я бы предпочел lua.
Re[4]: Написание своего DSL
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 10.09.20 15:37
Оценка:
МД> Я люблю только всё на безвозмедной основе.

Ищи, в интернете есть пиратская, только по правилам форума RSDN на неё нельзя давать ссылку.
Re[2]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 10.09.20 16:36
Оценка:
Здравствуйте, Рома Мик, Вы писали:

РМ>Всегда писал разбор руками, методом рекурсивного спуска. Другие методы даже не пробовал. Ну крутил в руках всякие yacc и подобные, но не более. Обычно собственно разбор — это очень быстро по сравнению с остальной работой по использованию полученного AST.


Ну совсем руками — это имхо перебор, но в целом — совершенно с тобой согласен
Маньяк Робокряк колесит по городу
Re[2]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 10.09.20 20:35
Оценка:
Здравствуйте, Эйнсток Файр, Вы писали:

ЭФ>Только Java, только Antlr


antlr это не только java
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 10.09.20 20:35
Оценка:
Здравствуйте, Marty, Вы писали:

M>Он умеет строить AST за тебя?


Этот — умеет. Но, имхо, лучше руками.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 10.09.20 20:57
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, Эйнсток Файр, Вы писали:


ЭФ>>Только Java, только Antlr


НС>antlr это не только java


Я его трогал, тогда была только джава. Но это было давно, да
Маньяк Робокряк колесит по городу
Re[2]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 10.09.20 21:56
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму".


НС>Не помню такого. Но технологический уровень описанного, скажем так, не особо выше плинтуса.


Было, было.

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


НС>Особо неверно вот это:

НС>

НС>Делайте тупой построчный разбор. В 90 процентов случаев этого достаточно для DSL


Хочу не согласиться. Но, может, это просто моя "ошибка выжившего". Обычно хватает тупых инишек. Иногда — древовидных, где вложенность определяется отступами. Ещё реже — построчник с более хитрым синтаксисом, нежели у инишки. Полноценный лексер/парсер по всем правилам науки обычно нужен, если хочется парсить ЯП.

Я вот приводил пример своего языка
Автор: Marty
Дата: 10.09.20
. Построчник, маркер директивы — '$', маркер продолжения строки (как в сишечке) — '\', маркеры для тупого сплита строки — ':' '-'. Зато через неделю уже в бой пошло.

НС>На прочтение и освоение чего то вроде драконов нужно потратить пару недель один раз в жизни, коли уж с профильным образованием не срослось. После этого пугаться лексеров и парсеров не будешь.


Дракон — драгон бук, что ли? Читал. Про образование — это типа задеть хотел? Я на кафедре ВТ учился, у нас было ближе к железу. Приятель учился на мат обеспечении ЭВМ, у них по парсерам был курс(ы). Я вот парсеры пишу между делом, а он 1С конфигурирует.


НС>Теперь про создание DSL в частности и языков в общем.


Спс. Хороший текст.

Но есть вопросы.
1) Примеры удачных DSL? Где взять? Чтобы с сорцами, чтобы понимать, как оно сделано. И сколько времени на это потрачено?
2) Тесты — хм. На них нет времени. Но у меня два отдела сотрудников, которые юзают мой DSL, если что-то не так — присылают исходники, которые его ломают.
3) Тесты — дампы AST как должно быть — руцами писать? У меня нет пары лет на вылизывание всего этого. Я за недельку по вечерам хочу тулзу сделать, чтобы снять часть рутины в основной работе
4) Вот пример
Автор: Marty
Дата: 10.09.20
исходника на моём языке. Он сейчас вполне всех устраивает. Если тебе не сложно, не мог бы ты коротенько написать, как бы ты сделал его разбор? Ну, и как можно улучшить сам язык

У нас эта шляпа используется для обмена данными по шинам RS-232, RS-485 и CAN по своему протоколу. Его автор краем глаза посматривал на CANopen. Сейчас вот появились сторонние устройства в нашей CAN-сетке с CANopen'ом, пришлось в том проекте пересесть на CANopen и этот язык отлично на него лег. А вот CANopen'овские EDS — для описания профилей устройств используют что? Да-да, тупые инишки. А могли бы нормально сделать, там куча бездельников, и за каждый сраный документ денег хотят
Маньяк Робокряк колесит по городу
Re[5]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 10.09.20 21:58
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Я его трогал, тогда была только джава.


НС>Ты не перепутал язык, на котором он написан и его таргеты? Таргет для С++ там уже лет 20 точно есть.


Думаю, что не перепутал. Думаю, ты про 20 лет загнул. Я его трогал вроде во второй половине нулевых, и плюсиков вроде не было. Ну, или я эпично затупил, что тоже возможно
Маньяк Робокряк колесит по городу
Re[3]: Написание своего DSL
От: Эйнсток Файр Мухосранск Странный реагент
Дата: 10.09.20 22:17
Оценка:
M> У меня нет пары лет на вылизывание всего этого

Найми за деньги специалиста.
Re[2]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 11.09.20 06:34
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Это очень зависит.

A>Нынешняя практика парсинга опирается на Хомского, дегенераивные грамматики и позиционные языки, похожие на английский.

Ну Хомский там очень условный, как только что-то практическое — начинается отклонение.
Регэкспы — давно не вкладываются в регулярные грамматики.
PEG используется каждым вторым.
И прочая и прочая.

A>Я в моей практике (не очень сложных парсеров) пришёл к противоположной методике.

A>Каждое слово языка имеет тэг. Первый символ (несколько символов) любой переменной — это тэг.
A>И этот тэг определяет в какой массив и какую структуру AST ты его записываешь.

Есть такие языки, но в целом это неудобно. А вот необязательные префиксы с ролью принудительного чтения токена как идентификатора или как ключевого слова (то есть минимум два таких) — да, критично важно для современного языка. И ещё один для тегов (аннотации Java, "атрибуты" C#, хотя слово слишком многозначно).

И ещё, я думаю, у тебя нет префикса для всяких == < + и тому подобных
значит, подход неполный.

A>PS.

A>Вот тут один персонаж (еретик) рассказывает про подобную методику. Только он ещё "иероглифы" (это такие своеобразные тэги) делает:

A>https://youtu.be/LxMj6ZYfbpU?t=898


Тоже забавно, но в общую практику вряд ли будет принято.
The God is real, unless declared integer.
Re[4]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 11.09.20 06:35
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:


НС>Нет. Просто не могу иначе объяснить проблему с элементарными вещами. Написать простейший LL парсер проще и быстрее, чем рукопашный непонятный парсер лопатить, а потом годами вылавливать из него баги.


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


M>>2) Тесты — хм. На них нет времени.


НС>Мне надо повторить тезис про технологический уровень?


Технологический уровень — как самоцель?


M>>4) Вот пример
Автор: Marty
Дата: 10.09.20
исходника на моём языке. Он сейчас вполне всех устраивает. Если тебе не сложно, не мог бы ты коротенько написать, как бы ты сделал его разбор? Ну, и как можно улучшить сам язык


НС>Зачем там знаки $ и #?

$ — признак директивы
# — комент
// — тоже комент
#!rdlc в начале — шебанг

НС>Что в нем такого, чего нельзя описать на yaml или json примерно теми же усилиями? Зачем тут вообще DSL, если, за исключением разве импортов да typedef, это простейшая древовидная структура? Если основные потребители — те кто использует плюсы и шарп, то зачем было изобретать свой нестандартный синтаксис? ?#!rdlc в начале зачем? Чем отличается include от import?


$include — это просто текстуальное включение внешнего файла, как в сишечке
$import — импорт другого устройства. Например, в роботе несколько плат, но пульт общается с одной мастер платой, однако ему нужно смотреть регистры других плат. Тогда мастер-плата их форвардит, включая регистры дочернего устройства (причем только нужные в данном устройстве, для экономии адресов). Что-то типа наследования в плюсах

  Пример
// Импортируемое устройство:
----
#!rdlc 

$once

$type [format="#08b";generator=cpp:flags;generator=csharp:enum] SafetyStatusBits : u, 32 - "Биты внутреннего регистра Safety Status"
    CELL_UNDERVOLTAGE  : 1 << 0  
$end_type

$type OtherSampleType : u32 - "Просто шляпа для примера"
    thrill    : 1<<5
    fear      : 1<<6
    shake     : 0x12<<7
    fly       : 'BF'
    or        :  shake | creep | bit 12
    CELL_UNDERVOLTAGE   : ~(shake | SafetyStatusBits:CELL_UNDERVOLTAGE | 1<<6) - "Вытащил константу из другого типа. Ну, тут можно было наверно как в C++ сделать ::"
$end_type


$device "driver" - Драйвер
 
  $namespace rw
 
    $group 
 
    [tag=speed]    speed_ctrl        : s8       - скорость в % от -100 до 100
                   position_ctrl     : u16      - позиция в градусах
 
  $namespace ro
 
    $group 
 
    [public]       public            : u8 - public
    [protected]    protected         : u8 - protected
    [private]      private           : u8 - private
 
    $group Group A
    [tag=speed]    speed             : s8     - текущая скорость в % от -100 до 100
                   position          : u16    - позиция
    $group [tag=status] Group B
                   temperature       : u8     - температура мотора
                   current           : s8     - текущий ток в % от -100 до 100
                   status            : u8     - состояние драйвера, битовое поле ошибок
----


// Импортирующее устройство:
----
#!rdlc
 
$device "robot" - Робот Хоббот-Боббот

    $import                        "driver" from "driver.rdl" as "Public1" prefix "pub1_"   - Import public
    $import [public]               "driver" from "driver.rdl" as "Public2" prefix "pub2_"   - Import public explicit
    $import [protected]            "driver" from "driver.rdl" as "Protected" prefix "prot_" - Import protected
    $import [private]              "driver" from "driver.rdl" as "Private" prefix "priv_"   - Import private
    $import [tag=speed]            "driver" from "driver.rdl" as "Speed" prefix "speed_imp_" - Import speed by tag
    $import [tag=status]           "driver" from "driver.rdl" as "Status" prefix "status_imp_" - Import status by tag
    $import [tag=speed,status]     "driver" from "driver.rdl" as "SpeedStatus" prefix "speed_status_imp_" - Import speed and status by tag
    $import [tag=speed;tag=status] "driver" from "driver.rdl" as "SpeedStatus2" prefix "speed_status_imp2_" - Import speed and status by tag - multiple tag attribute
----


НС>Что касается улучшения — очень сложно тебе что то посоветовать не варясь в вашей предметной области и не понимая смысла написанного. Если совсем обще — я бы убрал весь визуальный мусор, все эти ненужные значки, ввел бы нормальный конец строки и отказался от бейсиковых слешей для переноса.


Не обижай сишечный символ продолжения строки

На самом деле это было добавлено в самом конце, и стоило полкопейки. В результате развития хотелок пользователей добавились атрибуты (типа шарповых), и строки стали длинноваты, поэтому для удобства и добавил этот перенос.


НС>Синтаксис взял бы стандартный сишный. Сделал бы язык попонятнее — какие то префиксы в импорте, которых ниже по тексту нет, какой то ro, какие то неймспейсы сами по себе не ясно к чему относящиеся. Куча underscores.


Ну, у нас в протоколе все регистры делятся на два неймспейса — ReadOnly — статусные, и RW — управляющие
Сишный синтаксис — ну, такое. Например, я делал $typedef u32 uint32_t, ими 0 человек пользуется.
Язык для нас вполне понятный. Префиксы — это если в текущем и импортируемом устройстве есть одинаковые регистры, то при импорте можно задать префикс, чтобы не было ошибок.


НС>generator=cpp:struct как бы намекает, что вместе с целевой областью тут какая то мешанина инструкций для процессинга, зачем оно там? В той секции что капсами — куча повторяющихся слов.


Сразу видно, что это будет в целевом языке. Удобно. Мне и части коллег удобно так, другие задают всё в командной строке.
Про капс. Сишный коллега видно из кода дефайны тупо скопипастил, потому и капс. Повторяющихся — нет. Это параметры работы, на которой у нас BMS аккума сделан.


НС><< это что? Распиновка? >> может там быть? Если нет, то ты зря направленную, да еще и двойную лексему использовал. Достаточно симметричного значка типа -. Почему там слева везде только 1? Там может быть что то другое? Часто?


Это сдвиг, как в сишечке. Везде единичка — потому что это одиночные биты, другое тоже может быть, но редко. Обычно если нужна маска из нескольких бит, то обычно по or ('|') объединяются несколько ранее описанных битовых констант


НС>$typedef u8 : bool. По смыслу — новый тип u8, идентичный bool.


Нет. Новый тип bool, идентичный u8, как в сишечке.


НС>А судя по тому что ниже — наоборот.


А это паскалевский стиль. Тип переменной можно опустить, тогда будет принят u8, как самый часто встречающийся. Ну, некоторая нелогичность наверное есть, но вот никто, кроме тебя, не обращал внимания. Вообще, по языку вопросов никто не задавал, по языку — только хотелки, вопросы только по опциям командной строки возникают
Маньяк Робокряк колесит по городу
Re[5]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 11.09.20 17:39
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну, ок, возможно. Где бы еще посмотреть на что-то такое готовое, чтобы понять, как оно делается


Примеры к antlr? Можно начать с калькулятора.

M>>>2) Тесты — хм. На них нет времени.

НС>>Мне надо повторить тезис про технологический уровень?
M>Технологический уровень — как самоцель?

Как необходимое условие выдавать код качественно и быстро.

НС>>Зачем там знаки $ и #?

M>$ — признак директивы

Зачем?

M># — комент

M>// — тоже комент

Зачем два коммента и оба, судя по всему, однострочных?

M>#!rdlc в начале — шебанг


Зачем? Все равно ведь эту штуку только из билда надо запускать.

M>$include — это просто текстуальное включение внешнего файла, как в сишечке

M>$import — импорт другого устройства. Например, в роботе несколько плат, но пульт общается с одной мастер платой, однако ему нужно смотреть регистры других плат. Тогда мастер-плата их форвардит, включая регистры дочернего устройства (причем только нужные в данном устройстве, для экономии адресов).

Не многовато ли импортов для простенького файла?

M>На самом деле это было добавлено в самом конце, и стоило полкопейки.


Отличное оправдание. См. выше что я писал про экономию на разработке тула.

M>Язык для нас вполне понятный.


Понятный — не значит удобный. Домашнее задание: попробуй сократить размер своего примера хотя бы процентов на 30 без потери читаемости и семантического наполнения.

M> Префиксы — это если в текущем и импортируемом устройстве есть одинаковые регистры, то при импорте можно задать префикс, чтобы не было ошибок.


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

НС>>А судя по тому что ниже — наоборот.

M>А это паскалевский стиль.

Нет. В паскале type <TypeName> = type definition; end;

M> Тип переменной можно опустить, тогда будет принят u8, как самый часто встречающийся. Ну, некоторая нелогичность наверное есть, но вот никто, кроме тебя, не обращал внимания. Вообще, по языку вопросов никто не задавал


Ну вот и получился поэтому не особо удачный результат.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: rosencrantz США  
Дата: 11.09.20 18:31
Оценка:
Здравствуйте, Marty, Вы писали:

M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.


I. Генератор кода для небольшого количества бульменее стабильных исходных — пишите на чем умеете прямо на том языке, без DSL.
II. Нужно чуть больше — берите XML (джейсон, если хотите и есть норм библиотеки)
III. Делайте тупой построчный разбор. В 90 процентов случаев этого достаточно для DSL
IV. Если метите в разработчики компиляторов — используйте соответствующие инструменты
V. Если вы уже разработчик компилятора — пишите всё ручками, оно потом дешевле будет


Можете раскрыть тему п.2 vs п.3 и п.3 vs п.4? П.2 и п.4 приходилось делать в том или ином виде, но не понятно какая мотивация нужна для п.3.
Re[6]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 07:00
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>#!rdlc в начале — шебанг

НС>Зачем? Все равно ведь эту штуку только из билда надо запускать.

Разные форматы могут требовать разной обработки.
Опираться только на суффикс файла — может быть непригодно для метода сопровождения проекта, и вообще некузяво.

M>>$include — это просто текстуальное включение внешнего файла, как в сишечке

M>>$import — импорт другого устройства. Например, в роботе несколько плат, но пульт общается с одной мастер платой, однако ему нужно смотреть регистры других плат. Тогда мастер-плата их форвардит, включая регистры дочернего устройства (причем только нужные в данном устройстве, для экономии адресов).
НС>Не многовато ли импортов для простенького файла?

Один простой файл может организовывать весь проект, это типично.
The God is real, unless declared integer.
Re[5]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 07:05
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>Здравствуйте, Мёртвый Даун, Вы писали:


МД>>Здравствуйте, Эйнсток Файр, Вы писали:


ЭФ>>>Классический учебник по теме — https://www.springer.com/gp/book/9783642148453


МД>>Отбой, она платная. Я люблю только всё на безвозмедной основе.


A>Я нашёл полный pdf этой книжки. Если кому-то нужно, могу выслать.


Это находится легко. Вот рецензию по смыслу было бы полезнее. Пока что увидел, что там подходы заметно отличаются от типовых направлений "драконщины", но с обилием математики — продираться будет долго.
The God is real, unless declared integer.
Re[4]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 07:10
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>А что там такого? Покупать книжку за 50 долларов, чтобы убедиться, что там лажа я не буду.

A>Это лучше или хуже, чем вот это? Тут вся грамматика английского языка умещается на одной странице:

Грамматика английского в принципе не может быть умещена на одной странице, если описывать в достаточных деталях. Например, в каких сочетаниях допускаются need или dare в качестве вспомогательных глаголов, или с какими глаголами допустим инфинитив в качестве прямого дополнения, с какими — герундий, а с какими — оба, но с разным смыслом.

A>И напоминаю — мы обсуждаем DSL. Натуральные языки — это совершенно другая тема.


Если смотреть на правила какого-нибудь C#, в каком случае > будет считаться знаком сравнения, а в каких — закрывающей скобкой шаблона, то это уже заметно напоминает естественные языки. А C++ так вообще превращается в один из них со своей зависимостью от контекста, который ещё не задан
The God is real, unless declared integer.
Re[2]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 07:25
Оценка:
Здравствуйте, Мёртвый Даун, Вы писали:

МД>Здравствуйте, Marty, Вы писали:


МД>Нафига в ЖЖ? Ты бы еще в контактике запилил.


Вам-то чем плохо? Относительно надёжное хранилище (разве что весь СУП выльют), с надёжными постоянными ссылками, возможностью комментирования кем угодно (по openid), никто не фильтрует.
The God is real, unless declared integer.
Re[7]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 07:27
Оценка:
Здравствуйте, netch80, Вы писали:

N>Разные форматы могут требовать разной обработки.

N>Опираться только на суффикс файла — может быть непригодно для метода сопровождения проекта, и вообще некузяво.

Да не надо опираться ни на шебанг, ни на суффикс файла. Такие вещи — часть build pipeline, а не что то, что нужно запускать руками из шелла.

НС>>Не многовато ли импортов для простенького файла?

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

Что значит организовать весь проект и при чем тут дизайн DSL? Чем больше ты всякой ерунды напихаешь в DSL, тем менее удобным он будет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: GarryIV  
Дата: 12.09.20 07:31
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Точнее — парсинг и построение AST


M>Запилил статейку на эту тему со своими практиками, предлагаю обсудить. Но — с конструктивом, а не просто: "ты лошара неграмотная, я тебя на работу не возьму". Хочу понять, как таки это делать правильно и быстро.


За последнее время делал пару раз DSL.
Один раз на Котлине, по типу грейдла, то есть никакох парсеров и прочих антлров нету. Просто описание модели в kts по типу gradle.
Второй раз на долбанном питоне. Схема та же самая DSL тоже питоновский скрипт, по удобству и выразительности убогому питону до котлина далеко. Впрочем тоже довольно удобно получилось.

Все конечно зависит от, но самое простое и быстрое это DSL as code. Подход Gradle, Jenkins и т.д.
WBR, Igor Evgrafov
Re[8]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 07:35
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

N>>Разные форматы могут требовать разной обработки.

N>>Опираться только на суффикс файла — может быть непригодно для метода сопровождения проекта, и вообще некузяво.
НС>Да не надо опираться ни на шебанг, ни на суффикс файла. Такие вещи — часть build pipeline, а не что то, что нужно запускать руками из шелла.

При чём тут шелл? Это стандарт де факто пометки типа содержимого файла. Я много раз видел варианты типа

#! foo 3


соответственно "формат foo, версия 3". Транслятор видит пометку и переключается в соответствующий режим, редактор на них реагирует, и всё такое.

И чем тут противоречие с build pipeline, не понимаю. Как раз удобно просто сказать "вот эти файлы включить в проект" и дальше пусть машина думает, что с ними делать — и да, таки build pipeline обрабатывает эти указания.

НС>>>Не многовато ли импортов для простенького файла?

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

НС>Что значит организовать весь проект


Как в C, один файл с main() и ссылками на прочие декларации и/или исходники.

НС> и при чем тут дизайн DSL? Чем больше ты всякой ерунды напихаешь в DSL, тем менее удобным он будет.


Это верно ровно до тех пор, пока это действительно "ерунда", а не необходимые вещи.
The God is real, unless declared integer.
Re[3]: Написание своего DSL
От: alpha21264 СССР  
Дата: 12.09.20 08:42
Оценка:
Здравствуйте, netch80, Вы писали:

N>И ещё, я думаю, у тебя нет префикса для всяких == < + и тому подобных

N>значит, подход неполный.

С этим как раз проще — они же состоят из "не букв". То есть такой токен — сам по себе префикс.

Течёт вода Кубань-реки куда велят большевики.
Re[9]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 09:10
Оценка:
Здравствуйте, netch80, Вы писали:

N>При чём тут шелл?


При том что эта фича в основном на запуск из шелла заточена.

N>соответственно "формат foo, версия 3". Транслятор видит пометку и переключается в соответствующий режим, редактор на них реагирует, и всё такое.


Ну вот о том и речь, что совершенно служебные вещи тащим в исходник.

НС>>Что значит организовать весь проект

N>Как в C, один файл с main() и ссылками на прочие декларации и/или исходники.

Зачем? Почему не сделать файл проекта отдельным, не создавая ненужного шума в исходниках?

НС>> и при чем тут дизайн DSL? Чем больше ты всякой ерунды напихаешь в DSL, тем менее удобным он будет.

N>Это верно ровно до тех пор, пока это действительно "ерунда", а не необходимые вещи.

Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

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

... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 09:17
Оценка:
Здравствуйте, netch80, Вы писали:

N>Регэкспы — давно не вкладываются в регулярные грамматики.


Что значит не укладываются? 90% языков вполне укладываются, а еще 9% вполне себе покрываются простеньким хаком с переключением контекста лексера из парсера. Изобретать DSL, которому этого недостаточно — должна быть очень веская причина.

N>PEG используется каждым вторым.


Да ну нафик. PEG в чистом виде имеет совершенно непотребное O, а всякие вариации на тему packrat я пока не заметил чтобы стали прям так уж распространенными.
Вобщем, классические лексеры на регулярке пока вполне работают и дают очень неплохие результаты. Там проблема больше не с выразительностью, а с честной поддержкой юникода, не говоря уж о 32 битных вариациях. Старые алгоритмы сильно замедляются на 16 битах (я уж не говорю про 32), замена автомата на if (в antlr вроде так) заметно замедляет (хотя в сравнении с PEG разницы нет), а переход на диапазоны работает, но повышенный риск взрывного роста состояний ДКА остается проблемой.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 09:24
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

N>>При чём тут шелл?


НС>При том что эта фича в основном на запуск из шелла заточена.


С чего такой вывод? Shebang ещё с 80-х универсальный формат пометки "тип содержимого".

N>>соответственно "формат foo, версия 3". Транслятор видит пометку и переключается в соответствующий режим, редактор на них реагирует, и всё такое.

НС>Ну вот о том и речь, что совершенно служебные вещи тащим в исходник.

Что в этом служебного?

НС>>>Что значит организовать весь проект

N>>Как в C, один файл с main() и ссылками на прочие декларации и/или исходники.
НС>Зачем? Почему не сделать файл проекта отдельным, не создавая ненужного шума в исходниках?

Что такое "файл проекта" и какое отношение он имеет к такому исходнику?

НС>>> и при чем тут дизайн DSL? Чем больше ты всякой ерунды напихаешь в DSL, тем менее удобным он будет.

N>>Это верно ровно до тех пор, пока это действительно "ерунда", а не необходимые вещи.

НС>

НС>Главный критерий языка — удобство его использования человеком.


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

НС>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место


И строгой грамматике — тоже?
The God is real, unless declared integer.
Re[11]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 09:31
Оценка:
Здравствуйте, netch80, Вы писали:

N>Что в этом служебного?


Эта информация не имеет никакого отношения к domain.

НС>>Зачем? Почему не сделать файл проекта отдельным, не создавая ненужного шума в исходниках?

N>Что такое "файл проекта" и какое отношение он имеет к такому исходнику?

Это такой специальный файл,. в который выносится вся информация, которая нужна для сборки или дизайн-тайма, и не нужна для семантики исходников, связанной с целевым доменом.

N>Абсолютно верно. Вот и ставится пометка типа содержимого, которая понятна человеку не меньше, чем автосредствам.


ПОнятна не означает что нужна.

НС>>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

N>И строгой грамматике — тоже?

Если сможешь написать тулу, которая сможет обходится без нее — конечно.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 09:34
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, netch80, Вы писали:


N>>Регэкспы — давно не вкладываются в регулярные грамматики.


НС>Что значит не укладываются? 90% языков вполне укладываются,


Большинство движков регэкспов давно содержат фичи типа negative lookahead или ссылок типа \1.

НС> а еще 9% вполне себе покрываются простеньким хаком с переключением контекста лексера из парсера. Изобретать DSL, которому этого недостаточно — должна быть очень веская причина.


Если вы _внимательно_ прочитаете моё сообщение, то увидите, что оно было в контексте классификации Хомского, а не темы данного DSL или DSL вообще.

N>>PEG используется каждым вторым.


НС>Да ну нафик. PEG в чистом виде имеет совершенно непотребное O, а всякие вариации на тему packrat я пока не заметил чтобы стали прям так уж распространенными.


Вот именно что тех случаев, когда PEG уходит в высокие выси по времени работы, практиками систематически и достаточно интуитивно избегаются. Зато их привлекают принципы оформления правил.

И packrat в движках вокруг меня уже типовой вариант (вон недавно гонял tatsu... не пошёл, но причина не связана с грамматикой).

НС>Вобщем, классические лексеры на регулярке пока вполне работают и дают очень неплохие результаты. Там проблема больше не с выразительностью, а с честной поддержкой юникода, не говоря уж о 32 битных вариациях. Старые алгоритмы сильно замедляются на 16 битах (я уж не говорю про 32), замена автомата на if (в antlr вроде так) заметно замедляет (хотя в сравнении с PEG разницы нет), а переход на диапазоны работает, но повышенный риск взрывного роста состояний ДКА остается проблемой.


Видимо, это проблема средств вокруг вас (C# и прочее, да?)
Всё, что я в пару последних лет смотрел, этим не страдает — юникод это просто факт нижнего уровня, std::u32string в C++, unicode (str) в Python и так далее. Главное — не забывать вовремя вызывать нормализацию идентификаторов.
The God is real, unless declared integer.
Re[12]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 09:36
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Здравствуйте, netch80, Вы писали:


N>>Что в этом служебного?


НС>Эта информация не имеет никакого отношения к domain.


Расшифруйте, что именно из N+1 смыслов этого слова имеете в виду именно тут.

НС>>>Зачем? Почему не сделать файл проекта отдельным, не создавая ненужного шума в исходниках?

N>>Что такое "файл проекта" и какое отношение он имеет к такому исходнику?
НС>Это такой специальный файл,. в который выносится вся информация, которая нужна для сборки или дизайн-тайма, и не нужна для семантики исходников, связанной с целевым доменом.

Тогда вам следовало бы прочитать с самого начала, что речь идёт не о "файле проекта" в этом смысле, а о главном исходнике проекта.

N>>Абсолютно верно. Вот и ставится пометка типа содержимого, которая понятна человеку не меньше, чем автосредствам.

НС>ПОнятна не означает что нужна.

Ваше предложение по альтернативе? Имя файла, как уже говорил, подходит далеко не всегда.

НС>>>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

N>>И строгой грамматике — тоже?
НС>Если сможешь написать тулу, которая сможет обходится без нее — конечно.

"Мышки, станьте ёжиками" ™.
The God is real, unless declared integer.
Re[5]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 10:02
Оценка:
Здравствуйте, netch80, Вы писали:

НС>>Что значит не укладываются? 90% языков вполне укладываются,

N>Большинство движков регэкспов давно содержат фичи типа negative lookahead или ссылок типа \1.

И? Насколько эти фичи востребованны для лексического анализа DSL?

N>Если вы _внимательно_ прочитаете моё сообщение, то увидите, что оно было в контексте классификации Хомского, а не темы данного DSL или DSL вообще.


Ну и зачем оно в топике про DSL?

N>Видимо, это проблема средств вокруг вас (C# и прочее, да?)


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

N>Всё, что я в пару последних лет смотрел, этим не страдает — юникод это просто факт нижнего уровня


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

N>, std::u32string в C++, unicode (str) в Python и так далее.


И? Дальше то что? Оставаться на НКА и не строить ДКА, как большинство движков для регексов делают? Для парсеров языков это не очень хорошая стратегия часто.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[13]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 10:05
Оценка:
Здравствуйте, netch80, Вы писали:

НС>>Эта информация не имеет никакого отношения к domain.

N>Расшифруйте, что именно из N+1 смыслов этого слова имеете в виду именно тут.

Ну пипец. Название темы прочти.

N>Тогда вам следовало бы прочитать с самого начала, что речь идёт не о "файле проекта" в этом смысле, а о главном исходнике проекта.


Да понимаю я о чем ты тут пишешь. А вот ты меня — нет. Вопрос не в том что это за исходник, а в том насколько это удобно по сравнению с вариантом, когда нет никакого главного файла, а вся информация о сборке находится отдельно, а не в целевом DSL.

НС>>>>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

N>>>И строгой грамматике — тоже?
НС>>Если сможешь написать тулу, которая сможет обходится без нее — конечно.
N>"Мышки, станьте ёжиками" ™.

Можно расшифровать суть твоей претензии и как она стыкуется с разговором?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: vsb Казахстан  
Дата: 12.09.20 10:10
Оценка:
Здравствуйте, Marty, Вы писали:

M>Точнее — парсинг и построение AST


M>Хочу понять, как таки это делать правильно и быстро.


Я бы на antlr делал. У него даже сообщения об ошибках не самые плохие.

ИМХО построение AST это самое скучное. А вот что дальше с этим AST делать уже интересно. В тот же байткод его откомпилировать. Да ещё если система типов есть.
Re[6]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 10:17
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

N>>Если вы _внимательно_ прочитаете моё сообщение, то увидите, что оно было в контексте классификации Хомского, а не темы данного DSL или DSL вообще.


НС>Ну и зачем оно в топике про DSL?


Почему нет? Тут нормально, что тема локального разговора мигрирует в широких пределах вокруг исходной.
А вот не понять, что разговор ушёл на более общую тему — вот это точно неуместно.

НС>>>Что значит не укладываются? 90% языков вполне укладываются,

N>>Большинство движков регэкспов давно содержат фичи типа negative lookahead или ссылок типа \1.
НС>И? Насколько эти фичи востребованны для лексического анализа DSL?

Сильно зависит от того, какой DSL. Новые, да, лучше так не писать, но есть до чёрта всякого наследия.

N>>Видимо, это проблема средств вокруг вас (C# и прочее, да?)

НС>Ну да, если аргументов нет то надо искать проблемы в собеседнике.

Ещё не начинал. Хотя давно удивляюсь специфике вашего взгляда.

N>>Всё, что я в пару последних лет смотрел, этим не страдает — юникод это просто факт нижнего уровня

НС>Вопрос в том как устроен его анализ. Если внутри лексера не копаться то да, просто факт.

Мне достаточно того, что лексер умеет определять границы кодпунктов в том, что поступает на вход (в >99% случаев это utf-8). Проблемы с алгоритмами движения по тексту в utf-8 были решены ещё лет 15 назад.
Если вы знаете какие-то интересные проблемы на этом, расскажите, но только если они не специфичны для дотнета.

N>>, std::u32string в C++, unicode (str) в Python и так далее.

НС>И? Дальше то что? Оставаться на НКА и не строить ДКА, как большинство движков для регексов делают? Для парсеров языков это не очень хорошая стратегия часто.

Не совсем понял связь. По-вашему ДКА предполагает построение полной таблицы символов для лукапа, то есть 256 при восьмибитке и 64K при 16-битке?

Ну взгляните тогда хотя бы на re2c, он делает ДКА и любой юникод принимает без проблем. А вообще "кто хочет, ищет метод, а кто не хочет, ищет причину" — варианты всяких деревьев лукапов с оптимизацией для характерных диапазонов значений известны ещё со времён, когда Кнут был молодым.
The God is real, unless declared integer.
Re[14]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 10:24
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Эта информация не имеет никакого отношения к domain.

N>>Расшифруйте, что именно из N+1 смыслов этого слова имеете в виду именно тут.
НС>Ну пипец. Название темы прочти.

Ну пусть не имеет. Откуда идея, что весь файл целиком должен представлять только то, что "имеет отношение к domain"?

N>>Тогда вам следовало бы прочитать с самого начала, что речь идёт не о "файле проекта" в этом смысле, а о главном исходнике проекта.

НС>Да понимаю я о чем ты тут пишешь. А вот ты меня — нет. Вопрос не в том что это за исходник, а в том насколько это удобно по сравнению с вариантом, когда нет никакого главного файла, а вся информация о сборке находится отдельно, а не в целевом DSL.

Так мы этого просто не знаем без подробного знания как о специфике его задачи, так и об исполнителях. Может, там опрос показал, что им лучше так.

Типовые решения типа "правило интерпретации в имени, конфигурация сборки в выделенных файлах, каталоги src/ doc/ и т.п.", пригодные программистам, могут быть неудобны специалистам со специфическим бэкграундом. Завтра придут такие, кому вообще нужен один XLS на 100 страниц, и чтобы проект строился как UML схема включения между другими страницами (потому что им нужно быстро менять связи).

НС>>>>>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

N>>>>И строгой грамматике — тоже?
НС>>>Если сможешь написать тулу, которая сможет обходится без нее — конечно.
N>>"Мышки, станьте ёжиками" ™.
НС>Можно расшифровать суть твоей претензии и как она стыкуется с разговором?

Обычно не окупается. И ещё и имеет тяжёлые проблемы с развитием языка.
The God is real, unless declared integer.
Re[3]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 10:45
Оценка:
Здравствуйте, Marty, Вы писали:

M>Мне интересно, есть ли та волшебная пуля, которая за меня построит AST, опиши я язык в BNF или ещё каком виде.


Да, есть. Называется "наемные сотрудники".

M>Или вся эта шляпа с LL(X)/LR(X)б контекстно свободными/зависимыми грамматиками — просто псевдонаучно обоснованный развод для лохов, чтобы платили за то, что им вливают в уши?


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

Казалось бы, если для какого-то куска работы есть стройная математическая теория (что равносильно тому, что этот кусок работы кто-то полностью осознал и разложил по полочкам), надо радоваться и с удовольствием пользоваться этим теоретическим знанием. Но нет, привычка все делать на коленке побеждает, а усилия по пониманию десятка незнакомых терминов оказываются непомерными.
Re[7]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 11:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>А вот не понять, что разговор ушёл на более общую тему — вот это точно неуместно.


А, ну то есть было из разряда "у рыб шерсти нет ...". Сорри, думал раз ник не Serginio, то можно не сильно опасаться что собеседник на своей волне.

НС>>И? Насколько эти фичи востребованны для лексического анализа DSL?

N>Сильно зависит от того, какой DSL. Новые, да, лучше так не писать, но есть до чёрта всякого наследия.

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

N>>>Видимо, это проблема средств вокруг вас (C# и прочее, да?)

НС>>Ну да, если аргументов нет то надо искать проблемы в собеседнике.
N>Ещё не начинал.

Именно это ты и сделал и продолжаешь в том же духе. Ну ок, тогда можно и тебя пообсуждать.

N>>>Всё, что я в пару последних лет смотрел, этим не страдает — юникод это просто факт нижнего уровня

НС>>Вопрос в том как устроен его анализ. Если внутри лексера не копаться то да, просто факт.
N>Мне достаточно того, что лексер умеет определять

Я именно это и написал. Я же писал про то как это внутри устроено и какие проблемы бывают при написании собственных лексеров.

НС>>И? Дальше то что? Оставаться на НКА и не строить ДКА, как большинство движков для регексов делают? Для парсеров языков это не очень хорошая стратегия часто.

N>Не совсем понял связь. По-вашему ДКА предполагает построение полной таблицы символов для лукапа, то есть 256 при восьмибитке и 64K при 16-битке?

Нет, это наивный подход, который плохо работает.

N>Ну взгляните тогда хотя бы на re2c, он делает ДКА и любой юникод принимает без проблем.


Я смотрел, не переживай. И от того что там намного чаще натыкаешься на проблему экспоненциального роста количества состояний он не спасает.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[15]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 11:16
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ну пусть не имеет. Откуда идея, что весь файл целиком должен представлять только то, что "имеет отношение к domain"?


Потому что это упрощает чтение и понимание написанного.

N>Так мы этого просто не знаем без подробного знания как о специфике его задачи, так и об исполнителях.


И именно это я написал в самом начале.

НС>>>>>>Вещам, необходимым трансляторам и редакторам, в исходниках, которые пишет и читает человек, не место

N>>>>>И строгой грамматике — тоже?
НС>>>>Если сможешь написать тулу, которая сможет обходится без нее — конечно.
N>>>"Мышки, станьте ёжиками" ™.
НС>>Можно расшифровать суть твоей претензии и как она стыкуется с разговором?
N>Обычно не окупается. И ещё и имеет тяжёлые проблемы с развитием языка.

Ну вот и ответ тогда на заданный тобой вопрос.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Отредактировано 12.09.2020 11:17 Ночной Смотрящий . Предыдущая версия .
Re[10]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 12:14
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>

НС>Главный критерий языка — удобство его использования человеком.


И не только языка, кстати. А вообще, чего угодно. Но только пониманию, что мы работаем для людей (а не для компьютеров, науки, мира во всем мире и т.п.), в учебных заведениях, увы, не учат.
Re[11]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 12.09.20 12:16
Оценка:
Здравствуйте, Pzz, Вы писали:

НС>>

НС>>Главный критерий языка — удобство его использования человеком.

Pzz>И не только языка, кстати. А вообще, чего угодно.

Если говорить о программировании, для языка это особенно важно. И если для библиотеки еще можно как то пережить кривой API, то в случае с языком это фактически уничтожает его целевую функцию.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 12.09.20 13:27
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, netch80, Вы писали:


N>>Если смотреть на правила какого-нибудь C#, в каком случае > будет считаться знаком сравнения, а в каких — закрывающей скобкой шаблона, то это уже заметно напоминает естественные языки. А C++ так вообще превращается в один из них со своей зависимостью от контекста, который ещё не задан


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


А это уже от семантики зависит. Аналогом "обидной гадости" из одного слова может быть вызов вредной функции.
The God is real, unless declared integer.
Re[12]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.09.20 16:13
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Если говорить о программировании, для языка это особенно важно. И если для библиотеки еще можно как то пережить кривой API, то в случае с языком это фактически уничтожает его целевую функцию.


А бы отчасти поспорил.

Для какой-нибудь небольшой библиотеки, решающей какую-то конкретную проблему да, я с тобой соглашусь. Но если библиотека претендует на "фундаментальную" роль в программе, как стандартная библиотека языка, как стандартная библиотека операционной системы, как какой-то большой и всеобъемлющий framework, неудачный API может наделать много бед.
Re[5]: Написание своего DSL
От: alpha21264 СССР  
Дата: 12.09.20 18:59
Оценка:
Здравствуйте, netch80, Вы писали:

A>>А что там такого? Покупать книжку за 50 долларов, чтобы убедиться, что там лажа я не буду.

A>>Это лучше или хуже, чем вот это? Тут вся грамматика английского языка умещается на одной странице:

N>Грамматика английского в принципе не может быть умещена на одной странице, если описывать в достаточных деталях. Например, в каких сочетаниях допускаются need или dare в качестве вспомогательных глаголов, или с какими глаголами допустим инфинитив в качестве прямого дополнения, с какими — герундий, а с какими — оба, но с разным смыслом.


У этого мужика это в словаре. Это параметр "тип глагола".
Валентность глагола — это такой же параметр как грамматический род, и он используется в третьей таблицы.
Словарь — это не грамматика. Он может быть очень большим, но он регулярный.
То есть, увеличение объёма (данных) не приводит к увеличению сложности для автора программы.

Течёт вода Кубань-реки куда велят большевики.
Re[3]: Написание своего DSL
От: vdimas Россия  
Дата: 12.09.20 19:52
Оценка:
Здравствуйте, netch80, Вы писали:

N>Регэкспы — давно не вкладываются в регулярные грамматики.


Регеспы POSIX в точности описывают регулярную грамматику.
Может ты имел ввиду расширенные варианты, типа https://ru.wikipedia.org/wiki/PCRE?

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


N>PEG используется каждым вторым.


Тю!
Когда-то область компиляторостроения и вообще парсинга была "необъезженной", по ней неплохо готовили специалистов, бо отрасль нуждалась.
С приходом XML, JSON, YAML и прочих структурированных форматов практическая надобность в большом кол-ве специалистов по парсерам иссякла.

Отсюда те частые наблюдения, что когда необученные программеры начинают лабать нисходящие парсеры на коленке, т.е. методом проб и ошибок, получается банальный PEG.


A>>И этот тэг определяет в какой массив и какую структуру AST ты его записываешь.

N>Есть такие языки, но в целом это неудобно.

В целом это сводит парсер по сложности примерно к хеш-таблице. ))

Первый Фортран не далеко от такого ушел (до введения типизации):

переменные, имена которых начинаются с одной из шести букв I, J, K, L, M, N (например: IGREK5, LA, М, K2N3AB и т.д.), являются величинами целого типа, а с любой другой буквы (AL, X, DELTA и т.д.) — величинами вещественного типа.

Re[6]: Написание своего DSL
От: alpha21264 СССР  
Дата: 12.09.20 20:39
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, alpha21264, Вы писали:


A>>Я нашёл полный pdf этой книжки. Если кому-то нужно, могу выслать.


N>Это находится легко. Вот рецензию по смыслу было бы полезнее. Пока что увидел, что там подходы заметно отличаются от типовых направлений "драконщины", но с обилием математики — продираться будет долго.


А "драконщина" — это что?

Течёт вода Кубань-реки куда велят большевики.
Re[4]: Написание своего DSL
От: Михaил  
Дата: 12.09.20 21:28
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Хватать то хватает. Но ты продолжаешь делать ту же ошибку. Экономя человекодни на разработке инструмента теряешь человекогоды на его использовании. Активно используемый DSL (а делать его имеет смысл только при активном использовании) на много порядков умножает любое, даже копеечное удобство.


Случайно зашёл в дискуссию и, будучи не в теме, стало любопытно. Можно в двух словах, в каких случаях оптимально создание нового дсл? Почему-то казалось, что в большинстве случаев проще взять готовый язык (который большинству людей априори знаком), вроде python, lua, typescript/js, и на его основе городить скриптовый движок, чем изобретать новое «наречие».
Отредактировано 12.09.2020 21:31 Михaил . Предыдущая версия .
Re[6]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 00:49
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Ну, ок, возможно. Где бы еще посмотреть на что-то такое готовое, чтобы понять, как оно делается


НС>Примеры к antlr? Можно начать с калькулятора.


Я пока не буду целиком на всё отвечать, пока ещё раз решил попробовать antlr (кстати, javacc/sablecc лучше/хуже/удобнее/быстрее, не в курсе, не пробовал? JavaCC вроде в сипипи умеет, про саблю особо не искал), поднять свой технологический уровень, так сказать, и найти базу для дальнейшей дискуссии.

Хочу сгенерить парсер плюсиков. Грамматику взял тут — https://github.com/antlr/grammars-v4

По умолчанию генерится в джаву. Как через мавен сделать, чтобы генерился плюсовый код, пока не понял. Решил пойти по простому пути — https://en.wikipedia.org/wiki/ANTLR#Example
  Тут, внезапно
"generator=cpp:struct как бы намекает, что вместе с целевой областью тут какая то мешанина инструкций для процессинга, зачем оно там?"

Изначально у меня генераторы для типов задавались из командной строки. Потом я прикрутил в язык атрибуты, после чего (потому что могу) прикрутил атрибут generator с возможностью задания генератора для разных target-языков. Мне такое зашло, как и части коллег. Остальные, по старинке, используют командную строку. Не знаю, в какой последовательности аналогичные фичи (и когда — думаю, давно уже, но я не подглядывал) появились в ANTLR, но они есть. Но там ведь умные люди сидят, зачем эта мешанина?

// Common options, for example, the target language
 options
 {
  language = "CSharp";
 }


Присунул, куда показалось, надо, но что-то пошло не так
Автор: Marty
Дата: 13.09.20


Если не жалко, помоги мне поднять мой технологический уровень
Маньяк Робокряк колесит по городу
Отредактировано 13.09.2020 2:14 Marty . Предыдущая версия .
Re[5]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 02:06
Оценка:
Здравствуйте, Михaил, Вы писали:

М>Случайно зашёл в дискуссию и, будучи не в теме, стало любопытно. Можно в двух словах, в каких случаях оптимально создание нового дсл? Почему-то казалось, что в большинстве случаев проще взять готовый язык (который большинству людей априори знаком), вроде python, lua, typescript/js, и на его основе городить скриптовый движок, чем изобретать новое «наречие».


Если коротенько — ненужный мусор из конструкций языка. Так-то и на плюсиках в рамках плюсиков можно любой DSL написать, но плюсиковые конструкции будут заслонять DSL. Для других языков ровно то же самое вполне актуально.

Расскажу свою историю успехаза себя.

Давным давно, в одном НИИодной далёкой галактике, в рамках реализации проекта для вояк кто-то из разработчиков потыкал палочкой OPENcan. Присовывать какую-либо открытую реализацию OPENcan для микроконтроллеров в проект для вояк никто не решился, и по мотивам был создан свой стек протоколов для CAN, RS-232/UART и RS-485.

В протоколе (протокол не командный — типа — послать команду — получить ответ, а статусный — установить командный регистр/получить статусный региср) были предусмотрены ReadOnly регистры и ReadWrite регистры (на самом деле RW регистры — write-only, но в целях отладки их можно читать) — статусные регистры, когда устройство сообщает о своём состоянии, и управляющие RW-регистры, когда мастер начинает командовать.

Оформлялось для C/C++ это так:
#define RO_SOME_REGISTER00 0x00
#define RO_SOME_REGISTER01 0x01
#define RW_SOME_REGISTER00 0x00
#define RW_SOME_REGISTER01 0x01


Потом появились шарписты, которые пинали с компутера наши устройства. Стали писать:.
// $RO_BEGIN
#define RO_SOME_REGISTER00 0x00
#define RO_SOME_REGISTER01 0x01
// $RO_END

// $RW_BEGIN
#define RW_SOME_REGISTER00 0x00
#define RW_SOME_REGISTER01 0x01
// $RW_BEGIN

и написали парсер этого в сишарп.

Потом понадобилось передавать значения, ширшие, чем 1 байт. Их стали мапить на пачку однобайтных регистров. Константы для дефайнов и смещения вычислялись руками (и никто ни разу не облажался, ага).
Эта шляпа начала уже напрягать всех, и начальнеги отделов начали собираться пару раз в неделю перетереть на тему как нам реорганизовать рабкриннашу шляпу.

И тут появляюсь я. Я уже несколько месяцев работал в конторе, и так получилось, что тёрки происходили у меня под ухом (не опен спейс, но большое помещение с кучей народа. И свой уголок есть, и не скучно. Потом нас рассадили по отдельным кабинетам — стало реально скучно и уныло).

Погрел я уши, и запилил за пару вечеров инишку с генератором в C++. Народу понравилось, а потом понеслось
Автор: Marty
Дата: 10.09.20
Маньяк Робокряк колесит по городу
Re[7]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 02:11
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>>>Я нашёл полный pdf этой книжки. Если кому-то нужно, могу выслать.


N>>Это находится легко. Вот рецензию по смыслу было бы полезнее. Пока что увидел, что там подходы заметно отличаются от типовых направлений "драконщины", но с обилием математики — продираться будет долго.


A>А "драконщина" — это что?


Драгон бук — Ахо, Ульман и прочие, не? На самом деле, хоть и толстая, но так себе книжонка
Маньяк Робокряк колесит по городу
Re: Ничего не понял :)
От: Wolverrum Ниоткуда  
Дата: 13.09.20 02:36
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Точнее — парсинг и построение AST

Тут надо понимать, что AST для вашего DSL никто автоматом не сгенерит (ну, или я что-то реально пропустил). Его надо проектировать самому,

Как-то все очень сложно и непонятно. Нафига "проектировать AST" ?
Может, имелось в виду "создать грамматику DSL-я" ?

Наоборот, все очень последовательно и довольно просто:
1. Описываешь грамматику под, например HimeCC — там же расставляешь экшоны (обычно на правилах с участием терминалов)
2. После проверки и обработки имеешь набор классов и ресурсов, и работа сводится к наполнению кодом конкретных экшнов.
... (компилируешь)
3. Запускаешь в прод вкус — лепишь тесткейсов чтобы проверить что все плюс-минус работает ожидаемо, и — вперде.

Самое сложное и творческое — собственно выделенное жирным: иметь грамматику и перевести ее под конкретный генератор.
Re[7]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.20 04:36
Оценка:
Здравствуйте, alpha21264, Вы писали:

N>>Это находится легко. Вот рецензию по смыслу было бы полезнее. Пока что увидел, что там подходы заметно отличаются от типовых направлений "драконщины", но с обилием математики — продираться будет долго.


A>А "драконщина" — это что?


Вот это.
Есть три издания (на этом почему-то пишут, что второе, хотя по факту третье — может, потому, что состав авторов менялся).
В Сети находится, если поискать.

Теме парсинга посвящено страниц 200 с хвостом (там не только это — ещё кодогенерации, оптимизации и пр.), но большинство это доказательства применимости разных хитрых формализмов. Прочитать один раз — однозначно стоит; решать задачи — уже по вкусу; верить важности — нет, по крайней мере пока основные проблемы с реальными языками программирования это не как соблюсти типовой теоретизм, а как быть, если он уже нарушен (как в C++).
The God is real, unless declared integer.
Re[5]: Написание своего DSL
От: vdimas Россия  
Дата: 13.09.20 11:36
Оценка:
Здравствуйте, netch80, Вы писали:

V>>Отсюда те частые наблюдения, что когда необученные программеры начинают лабать нисходящие парсеры на коленке, т.е. методом проб и ошибок, получается банальный PEG.

N>Момент, когда "отрасль нуждалась", я пропустил, видимо.

До последней четверти 90-х примерно.
У меня курсовик в 94-м был — свой парсеропостроитель из своего метаописания (на второй итерации это метаописание читалось уже сгенерированным кодом), потом он пошёл как часть диплома.
Тогда это был пик востребованности.

Плюс ограничения тогдашней техники на объемы памяти и быстродействия тоже требовали далеко не наколенных решений, типа PEG (вернее, более общего класса наколенных парсеров — комбинаторных).

А потом появились (скорее созрели) достаточно развитые ср-ва построения парсеров, и вкупе с Java+XML, плюс развитие интернета — всё это стало видоизменять IT, придавать всё больший уклон от фундаментальных вещей к прикладным. Сверху усилилось "память больше не ресурс" и т.д.


N>Я наблюдаю, да, невысокий, но постоянный спрос


Увы, спрос не постоянен.
Я одно время искал себя именно по этой теме, бо в "просто программеры" идти было скучновато...
Выяснилось, что каждая такая задача — "одноразовая".
Т.е., всё время держать штат подготовленных по этой области спецов любой отдельно взятой конторе бессмысленно.
И обратное тоже верно — достаточному кол-ву спецов сложно найти полную занятость именно по этой области.


N>и всё равно при этом решения на PEG занимают заметную нишу.


Вряд ли именно строгий PEG, просто PEG — это уже мем над целым направлением комбинаторных потуг.
Да, любой доведенный до практического применения комбинаторный парсер будет в существенной части своей реализации PEG, но не обязательно весь.
На то он и комбинаторный парсер. ))


N>Может быть, как раз потому, что они естественно ложатся на мышление того, кто ещё не загнан правилами LL/LR на конкретные рельсы мышления и/или не понимает важности их ограничений (а, может, это одно и то же условие).


Ну да, принцип разработки незамысловат: "водим пальчиком по разбираемому тексту и прикидываем — как бы это можно было зачитать".
При таком подходе работает "тесты вперёд", бо все конфликты могут быть обнаружены только на реальных данных, т.е. вопрос широты тестирования и банального везения тут не праздный.
Формальные грамматики, наоборот, могут судить о непротиворечивости грамматики еще на этапе её анализа (или построения по ней парсера).

В общем, это примерно как отличие статической типизации от динамической.
Второй я никогда не доверял.


A>>>>И этот тэг определяет в какой массив и какую структуру AST ты его записываешь.

N>>>Есть такие языки, но в целом это неудобно.
V>>В целом это сводит парсер по сложности примерно к хеш-таблице. ))

N>Ладно, на старый BASIC с его A! — целое, A$ — строка, A% — вещественное. Всё равно выражения надо парсить.


Но тип выражения выводить не надо, я это имел ввиду.


N>Нет, это не "первый" Fortran. Это уже правила Fortran II.


Возможно.
Я писал на таком на EC-1022. ))
Отредактировано 18.09.2020 1:11 vdimas . Предыдущая версия .
Re[7]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 14:57
Оценка:
Здравствуйте, Marty, Вы писали:

M>Я пока не буду целиком на всё отвечать, пока ещё раз решил попробовать antlr (кстати, javacc/sablecc лучше/хуже/удобнее/быстрее, не в курсе, не пробовал?


Саблю смотрел, благо исходники вполне читаемы. Проще antlr, но для DSL наверняка сойдет.

M>Хочу сгенерить парсер плюсиков.


А чего сразу не естественного языка? Ну а чего мелочиться.
Я ж говорю — начни с калькулятора, потом паскаль.

M>Если не жалко, помоги мне поднять мой технологический уровень


Тут я тебе вряд ли чем смогу помочь, я 4 версию уже не смотрел, задачи по теме закончились году в 16.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 15:14
Оценка:
Здравствуйте, Marty, Вы писали:

M>Давным давно, в одном НИИодной далёкой галактике, в рамках реализации проекта для вояк кто-то из разработчиков потыкал палочкой OPENcan. Присовывать какую-либо открытую реализацию OPENcan для микроконтроллеров в проект для вояк никто не решился, и по мотивам был создан свой стек протоколов для CAN, RS-232/UART и RS-485.


Если тебе в протоколы, то, возможно, имеет смысл для вдохновения посмотреть на https://developers.google.com/protocol-buffers/docs/proto. Или на https://www.microsoft.com/en-us/research/project/spec/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fprojects%2Fspecsharp
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.20 16:35
Оценка:
Здравствуйте, Marty, Вы писали:

M>Хочу сгенерить парсер плюсиков. Грамматику взял тут — https://github.com/antlr/grammars-v4


Если "плюсики" это C++ — то, надеюсь, это шутка. Потому что плюсы сделаны так, чтобы парсить их было не просто, а очень сложно. Это типа результат естественного развития, но результат от этого не лучше.

Для начала Most vexing parse. Точное понимание конструкции зависит от определений, которые на этот момент могли ещё не быть прочитаны из файла (они появятся позже в том же классе).
Оно же сбоку: функция или переменная на разных платформах.

Доказательство неразрешимости полной грамматики.

В C++11 (и позже), последовательность >> — или сдвиг вправо, или два закрытия шаблона.
В C++20, те же проблемы с spaceship operator ("<=>").

И прочая и прочая (тысячи их).

В ANTLR, конечно, какой-то пример, но минимальный; полный парсер, чтобы получить хотя бы AST, должен включать в себя из-за описанных свойств интерпретатор логики шаблонов (а вслед этим и значительного подмножества языка).

Лучше вызывайте clang, он за вас всё сделает
The God is real, unless declared integer.
Re[8]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 19:47
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Хочу сгенерить парсер плюсиков.


НС>А чего сразу не естественного языка? Ну а чего мелочиться.

НС>Я ж говорю — начни с калькулятора, потом паскаль.

Ну, например, потому, что калькулятор я и в рукопашную за полдня напишу рекурсивным спуском, а плюсики хочу парсить для своего пет-проекта, руками уже писал, хочу по науке попробовать.

Тем более, что грамматика уже умными людьми описана
Маньяк Робокряк колесит по городу
Отредактировано 13.09.2020 19:49 Marty . Предыдущая версия .
Re[8]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 19:59
Оценка:
Здравствуйте, netch80, Вы писали:

N>В ANTLR, конечно, какой-то пример, но минимальный; полный парсер, чтобы получить хотя бы AST, должен включать в себя из-за описанных свойств интерпретатор логики шаблонов (а вслед этим и значительного подмножества языка).


Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать


N>Лучше вызывайте clang, он за вас всё сделает


Это скучно
Маньяк Робокряк колесит по городу
Re[7]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 20:01
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Давным давно, в одном НИИодной далёкой галактике, в рамках реализации проекта для вояк кто-то из разработчиков потыкал палочкой OPENcan. Присовывать какую-либо открытую реализацию OPENcan для микроконтроллеров в проект для вояк никто не решился, и по мотивам был создан свой стек протоколов для CAN, RS-232/UART и RS-485.


НС>Если тебе в протоколы, то, возможно, имеет смысл для вдохновения посмотреть на https://developers.google.com/protocol-buffers/docs/proto. Или на https://www.microsoft.com/en-us/research/project/spec/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fprojects%2Fspecsharp


Да у нас уже технологии отлажены, никто менять ничего не будет. Только улучшать
Маньяк Робокряк колесит по городу
Re[9]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 20:06
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну, например, потому, что калькулятор я и в рукопашную за полдня напишу рекурсивным спуском,


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

M> а плюсики хочу парсить для своего пет-проекта,


Тебе уже сказали несколько человек, что плюсы это очень плохой вариант.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[9]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 20:06
Оценка:
Здравствуйте, Marty, Вы писали:

M>Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать


Между плюсами и калькулятором у тебя нет промежуточных положений?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[8]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 13.09.20 20:06
Оценка:
Здравствуйте, Marty, Вы писали:

M>Да у нас уже технологии отлажены, никто менять ничего не будет. Только улучшать


Ты сам попросил примеры.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 20:45
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Ну, например, потому, что калькулятор я и в рукопашную за полдня напишу рекурсивным спуском,


НС>А генератором — за полчаса. И суть не в написать, а в научиться.


Научится — дело хорошее, но если задачу не решает, то можно и отложить.


M>> а плюсики хочу парсить для своего пет-проекта,


НС>Тебе уже сказали несколько человек, что плюсы это очень плохой вариант.


И что теперь? Завернутся в простыню и ползти на кладбище?
Маньяк Робокряк колесит по городу
Re[9]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 13.09.20 20:48
Оценка:
Здравствуйте, Marty, Вы писали:

N>>В ANTLR, конечно, какой-то пример, но минимальный; полный парсер, чтобы получить хотя бы AST, должен включать в себя из-за описанных свойств интерпретатор логики шаблонов (а вслед этим и значительного подмножества языка).

M>Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать

Ну почему сразу калькулятор. Твои хитрые файлы вполне тут подойдут.

N>>Лучше вызывайте clang, он за вас всё сделает

M>Это скучно

Ну блин реально терять пару десятков человеко-лет на повторение того, что крупные корпорации и так делают...
Да, лучше взять другую задачу, тут я полностью согласен.
The God is real, unless declared integer.
Re[10]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 20:53
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать


НС>Между плюсами и калькулятором у тебя нет промежуточных положений?


На текущий момент практически нужных — нет. Но обещаю тебе, когда появятся — обязательно сделаю ещё один подход к снаряду.
Маньяк Робокряк колесит по городу
Re[9]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 20:59
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

M>>Да у нас уже технологии отлажены, никто менять ничего не будет. Только улучшать


НС>Ты сам попросил примеры.


А можно контекст, где я что просил? А то я тут немного его видимо потерял. Вроде примеров стеков протоколов я не просил
Маньяк Робокряк колесит по городу
Re[10]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 13.09.20 21:15
Оценка:
Здравствуйте, netch80, Вы писали:

M>>Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать


N>Ну почему сразу калькулятор. Твои хитрые файлы вполне тут подойдут.


Ну только оно уже работает. Ну ты понил, да?


N>Ну блин реально терять пару десятков человеко-лет на повторение того, что крупные корпорации и так делают...


Пару десятков человеко-лет? Я столько не проживу

Колоризер для 03их плюсиков я еще в первой половине нулевых написал, месяц, ну, может два, практически со студенческой скамьи. И да, он умел в typedef, struct/class и подсвечивал их отдельно другим цветом. Сейчас плюсики несколько усложнились, но и я уже не тот


N>Да, лучше взять другую задачу, тут я полностью согласен.


Так мне эта нужна. Вот я и подумал, может, мне инструменты помогут
Маньяк Робокряк колесит по городу
Re[11]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 14.09.20 04:32
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>Похоже, что ручной работы что так, что эдак — куча. Оставить что ли изучение ANTLR до тех времён, когда надо будет калькулятор написать

N>>Ну почему сразу калькулятор. Твои хитрые файлы вполне тут подойдут.
M>Ну только оно уже работает. Ну ты понил, да?

Зато проба реализации на другом средстве обычно помогает находить баги и проблемы дизайна.

N>>Ну блин реально терять пару десятков человеко-лет на повторение того, что крупные корпорации и так делают...

M>Пару десятков человеко-лет? Я столько не проживу
M>Колоризер для 03их плюсиков я еще в первой половине нулевых написал, месяц, ну, может два, практически со студенческой скамьи. И да, он умел в typedef, struct/class и подсвечивал их отдельно другим цветом. Сейчас плюсики несколько усложнились, но и я уже не тот

Ну если сделать на уровне _до_ того, как начнут действовать все описанные проблемы — то можно и на ANTLR и вообще на чём угодно.

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

N>>Да, лучше взять другую задачу, тут я полностью согласен.

M>Так мне эта нужна. Вот я и подумал, может, мне инструменты помогут

The God is real, unless declared integer.
Re[11]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 14.09.20 06:54
Оценка:
Здравствуйте, Marty, Вы писали:

НС>>А генератором — за полчаса. И суть не в написать, а в научиться.

M>Научится — дело хорошее, но если задачу не решает, то можно и отложить.

И потом опять сделать ту же ошибку?

M>>> а плюсики хочу парсить для своего пет-проекта,

НС>>Тебе уже сказали несколько человек, что плюсы это очень плохой вариант.
M>И что теперь? Завернутся в простыню и ползти на кладбище?

Начинать с более простых задач. Не нравятся тулы — попробуй руками реализовать хотя бы парсер Пратта. Работы на пару часов, зато потом свой DSL полноценными выражениями сможешь расширить.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[11]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 14.09.20 06:54
Оценка:
Здравствуйте, Marty, Вы писали:

M>На текущий момент практически нужных — нет. Но обещаю тебе, когда появятся — обязательно сделаю ещё один подход к снаряду.


Тут есть опасность того, что ты сейчас считаешь написание нормальных парсеров чем то очень сложным и не видишь очевидных мест применения.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[11]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 14.09.20 07:08
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну только оно уже работает. Ну ты понил, да?


Во-первых там могут быть ошибки, во-вторых когда ты опишешь грамматику у тебя будет более ясное понимание где у тебя узкие места и в какую сторону можно двигаться.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 14.09.20 07:10
Оценка:
Здравствуйте, Marty, Вы писали:

НС>>Ты сам попросил примеры.

M>А можно контекст, где я что просил? А то я тут немного его видимо потерял. Вроде примеров стеков протоколов я не просил

M>1) Примеры удачных DSL? Где взять?

... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: Написание своего DSL
От: alpha21264 СССР  
Дата: 14.09.20 15:59
Оценка:
Здравствуйте, Михaил, Вы писали:

М>Случайно зашёл в дискуссию и, будучи не в теме, стало любопытно. Можно в двух словах, в каких случаях оптимально создание нового дсл?


Когда ты хочешь решать задачу не на языке программирования, а на языке задачи.
Например, если ты пишешь шахматную программу, и хочешь изъясняться на языке ходов и позиций, а не циклов и подпрограмм.

Течёт вода Кубань-реки куда велят большевики.
Re[7]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.09.20 19:30
Оценка:
Здравствуйте, alpha21264, Вы писали:

A>А "драконщина" — это что?


Классический трехтомник Ахо и Ульмана про компиляторы.

https://www.amazon.com/Compilers-Principles-Techniques-Alfred-Aho/dp/0201100886/ref=pd_lpo_14_t_1/134-1203048-9544724?_encoding=UTF8&amp;pd_rd_i=0201100886&amp;pd_rd_r=07253912-2e8f-436b-853d-95462d30438c&amp;pd_rd_w=NKkWd&amp;pd_rd_wg=r5hpf&amp;pf_rd_p=7b36d496-f366-4631-94d3-61b87b52511b&amp;pf_rd_r=8T5NEE0SEN01G14RV9N7&amp;psc=1&amp;refRID=8T5NEE0SEN01G14RV9N7

Название получил за ресунок на обложке.
Re[4]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.09.20 19:43
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Первый Фортран не далеко от такого ушел (до введения типизации):


В первом фортране оператор цикла мог выглядеть так:

DO I = 10, 100


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

DOI = 10, 100


А присваивание могло выглядеть так:

DOI = 10


Потому, что никто не запрещал назвать переменную DOI. Поэтому не дочитав до запятой, компилятор Фортрана даже и не знал, компилирует он присваивание или оператор цикла.

Насколько я понимаю, синтаксис Фортрана вообще нельзя описать контекстно-свободной грамматикой. А ты говоришь, хеш-таблицы...
Re[9]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.09.20 19:48
Оценка:
Здравствуйте, Marty, Вы писали:

N>>Лучше вызывайте clang, он за вас всё сделает


M>Это скучно


Напиши парсер ANSI C (без плюсов). Это и нескучно, и посильно.
Re[5]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 02:15
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>А мог и так, потому что пробелы в нем не были значимы совсем:


Я на таком писал и?


Pzz>Поэтому не дочитав до запятой, компилятор Фортрана даже и не знал, компилирует он присваивание или оператор цикла.


А зачем знать?
На одной строке один оператор языка или ошибка трансляции.


Pzz>Насколько я понимаю, синтаксис Фортрана вообще нельзя описать контекстно-свободной грамматикой.



Синтаксис каждой отдельно взятой строки того Фортрана можно описать регулярной грамматикой (по Холмскому, а не перловой).
Re[6]: Написание своего DSL
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.09.20 05:25
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А зачем знать?

V>На одной строке один оператор языка или ошибка трансляции.

Оператор-то один. Только надо далеко продвинуться, чтобы понять, это оператор присваивания или цикла

Pzz>>Насколько я понимаю, синтаксис Фортрана вообще нельзя описать контекстно-свободной грамматикой.


V>

V>Синтаксис каждой отдельно взятой строки того Фортрана можно описать регулярной грамматикой (по Холмскому, а не перловой).

Уже даже просто выражения со скобками не описываются регулярной грамматикой.
Re[7]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 10:32
Оценка:
Здравствуйте, Pzz, Вы писали:

V>>А зачем знать?

V>>На одной строке один оператор языка или ошибка трансляции.
Pzz>Оператор-то один. Только надо далеко продвинуться, чтобы понять, это оператор присваивания или цикла

'DO' space* var space* '=' space* digit [space* ',' space* digit [space* ',' space* digit]]



V>>Синтаксис каждой отдельно взятой строки того Фортрана можно описать регулярной грамматикой (по Холмскому, а не перловой).

Pzz>Уже даже просто выражения со скобками не описываются регулярной грамматикой.

Поймал. ))
Я в голове прикидывал остальные операторы языка.
Re[5]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 10:39
Оценка:
Здравствуйте, netch80, Вы писали:

N>Большинство движков регэкспов давно содержат фичи типа negative lookahead


Это всё еще регулярная грамматика по Холмскому.
(это что-то "синтаксического сахара" описания грамматики)


N>или ссылок типа \1.


А здесь уже зависит от.
Обратная ссылка может сделать грамматику контекстно-зависимой.
(т.е. класс контекстно-свободных, то бишь стековых грамматик пропускается, что забавно)


N>И packrat в движках вокруг меня уже типовой вариант


Не нашлось рядом никого с профильным образованием?
Re[7]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 10:43
Оценка:
Здравствуйте, netch80, Вы писали:

N>По-вашему ДКА предполагает построение полной таблицы символов для лукапа, то есть 256 при восьмибитке и 64K при 16-битке?


Или таблицу подстановки до ДКА.


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


Принцип устройства такой таблицы (хеш, дерево или индексный массив), а так же декомпозиция ДКА не делает грамматику нерегулярной.
Это всё относится, скорее, к оптимизации реализации.
Re[9]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 10:45
Оценка:
Здравствуйте, netch80, Вы писали:

N>Так теперь уже ты не ограничиваешь только созданием DSL. Сказано же — для лексического анализа.


Наверно имелось ввиду, что синтаксический анализатор может быть тоже ДКА, а не стековой машинкой.
Зависит от DSL.
Re[6]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.09.20 12:09
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Это всё еще регулярная грамматика по Холмскому.

V>(это что-то "синтаксического сахара" описания грамматики)

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



N>>или ссылок типа \1.


V>А здесь уже зависит от.

V>Обратная ссылка может сделать грамматику контекстно-зависимой.
V>(т.е. класс контекстно-свободных, то бишь стековых грамматик пропускается, что забавно)

Да.

N>>И packrat в движках вокруг меня уже типовой вариант


V>Не нашлось рядом никого с профильным образованием?


Как профильное образование мешает наличию packrat в PEG?
The God is real, unless declared integer.
Отредактировано 15.09.2020 12:21 netch80 . Предыдущая версия .
Re[8]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.09.20 12:19
Оценка:
Здравствуйте, vdimas, Вы писали:

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


V>Принцип устройства такой таблицы (хеш, дерево или индексный массив), а так же декомпозиция ДКА не делает грамматику нерегулярной.

V>Это всё относится, скорее, к оптимизации реализации.

Ну я о том же. А НС почему-то намекает на тяжёлые проблемы, вплоть до невозможности работы.
The God is real, unless declared integer.
Re[7]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 12:39
Оценка:
Здравствуйте, netch80, Вы писали:

V>>Это всё еще регулярная грамматика по Холмскому.

V>>(это что-то "синтаксического сахара" описания грамматики)
N>А не начинает зависеть от сложности выражений? Я этот момент уже плохо помню, но, кажется, сложность начинает "перемножаться" на каждый такой терм.

Не принципиально, т.к. размер таблицы переходов (если парсер табличный), зависит от кол-ва состояний, а не от кол-ва дуг (переходов).

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


V>>Не нашлось рядом никого с профильным образованием?

N>Как профильное образование мешает наличию packrat в PEG?

Ну, наколенный детерминированный LL(1) не сложнее.
Или можно взять бизоны для LR(x)/GLR-граматик или ANTLR для LL(1).

Просто есть же стандартные бока с левосторонней рекурсией для нисходящих парсеров, что там с этим у packrat?
ANTLR сам производит факторизацию грамматики для удаления левосторонней рекурсии, в этом его главная киллер-фича, как по мне.
Т.е. можно продолжать описывать правила в "человеческом виде", а далее "машина разберется".
И что характерно — если не разберется, то сообщит об этом еще на этапе построения парсера.
А наколенный нисходящий парсер может однажды уйти в stack overflow на машине клиента. ))
Отредактировано 15.09.2020 12:40 vdimas . Предыдущая версия .
Re[8]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.09.20 12:43
Оценка:
Здравствуйте, vdimas, Вы писали:

Pzz>>Оператор-то один. Только надо далеко продвинуться, чтобы понять, это оператор присваивания или цикла


V>'DO' space* var space* '=' space* digit [space* ',' space* digit [space* ',' space* digit]]

V>

Там это так не работало, например, вот это должно было быть понято как оператор DO:

D   O1   0I   J=1,1   0

до метки 10 по переменной IJ от 1 до 10 включительно.

Реально можно считать, что там вначале некий... мнэээ... прототип лексического анализатора делил весь ввод на текстовые константы (в кавычках или холлеритовские) и всё остальное, а дальше работал грамматический анализатор, который уже пробелы не знал в своих определениях.

V>>>Синтаксис каждой отдельно взятой строки того Фортрана можно описать регулярной грамматикой (по Холмскому, а не перловой).

Pzz>>Уже даже просто выражения со скобками не описываются регулярной грамматикой.

V>Поймал. ))

V>Я в голове прикидывал остальные операторы языка.

Остальные — да, по крайней мере до введения всяких "структурных IF" в F77.
The God is real, unless declared integer.
Re[9]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 12:50
Оценка:
Здравствуйте, netch80, Вы писали:

N>Там это так не работало, например, вот это должно было быть понято как оператор DO:


Я вообще изначально написал без space*, потом добавил.
В общем, пропуск пробелов — не принципиальный, реализуется одним лишним if в парсере.

И да, тот Фортран был позиционным, т.е. до какой-то позиции в строке операторы не должны были встречаться, там можно было только метки размещать, что еще больше упрощало парсер.
Re[10]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.09.20 12:53
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Я вообще изначально написал без space*, потом добавил.

V>В общем, пропуск пробелов — не принципиальный, реализуется одним лишним if в парсере.

Да. Но логика не соответствует современной.

V>И да, тот Фортран был позиционным, т.е. до какой-то позиции в строке операторы не должны были встречаться, там можно было только метки размещать, что еще больше упрощало парсер.


Ну не то чтобы упрощало... значения в позициях 7-72 всех строк надо было таки разбирать как я описал.
The God is real, unless declared integer.
Re[8]: Написание своего DSL
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.09.20 13:25
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Это всё еще регулярная грамматика по Холмскому.

V>>>(это что-то "синтаксического сахара" описания грамматики)
N>>А не начинает зависеть от сложности выражений? Я этот момент уже плохо помню, но, кажется, сложность начинает "перемножаться" на каждый такой терм.

V>Не принципиально, т.к. размер таблицы переходов (если парсер табличный), зависит от кол-ва состояний, а не от кол-ва дуг (переходов).


V>Т.е., грубо, если в при обычной дуге у нас почти во всех клетках будет из данного состояния переход в ошибочное, и только по нужному символу (символам) в следующее (следующие), то тут наоборот — по заданным символам будет переход в ошибочное состояние, а по остальным — в целевое (целевые).


Я вот к чему. Представь себе выражение типа ^X(?!.*zuka$)[a-z]+$
(Не будем обсуждать психические свойства автора, он просто сэкономил на мышлении.)
Но итоговая машина состояний должна одновременно сочетать два поиска — по нужным символам и по недопустимой комбинации. Значит, у нас получится u-простое и u-после-z, a-простое и a-после-zuk...
теперь усложним заменой zuka на (zuka){3,30}buka ... таблица всё ещё конечна, но состояний до чёрта.
Кто выдержит составление такой таблицы, и на каком количестве состояний генератор решит "а не пошло бы оно к бениной бабушке"?

Или я не вижу тут ещё какого-то фокуса?

V>>>Не нашлось рядом никого с профильным образованием?

N>>Как профильное образование мешает наличию packrat в PEG?

V>Ну, наколенный детерминированный LL(1) не сложнее.

V>Или можно взять бизоны для LR(x)/GLR-граматик или ANTLR для LL(1).

V>Просто есть же стандартные бока с левосторонней рекурсией для нисходящих парсеров, что там с этим у packrat?


Фиг его знает как у packrat в принципе, но например последний мной виденный PEG с packrat — TatSu — явно пишет в доке, что умеет её раскручивать. Я это не пробовал, не дошли до такой глубины.

А вообще в PEG это принципиально решается элементом типа e* — вики его явно перечисляет в базовых конструктах, что даёт варианты типа

addsub :== muldiv (("+"/"-") muldiv)*

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

V>ANTLR сам производит факторизацию грамматики для удаления левосторонней рекурсии, в этом его главная киллер-фича, как по мне.


И у него явно описаны ограничения возможности этой его логики. Я бы в сложных случаях на это не залагался.

V>Т.е. можно продолжать описывать правила в "человеческом виде", а далее "машина разберется".

V>И что характерно — если не разберется, то сообщит об этом еще на этапе построения парсера.
V>А наколенный нисходящий парсер может однажды уйти в stack overflow на машине клиента. ))

В наколенном нисходящем... ну если его автор не протестировал, то ССЗБ, но таки делается такой же перевод в цикл, как в базовом PEG.
The God is real, unless declared integer.
Re[9]: Написание своего DSL
От: vdimas Россия  
Дата: 15.09.20 15:18
Оценка:
Здравствуйте, netch80, Вы писали:

N>Но итоговая машина состояний должна одновременно сочетать два поиска — по нужным символам и по недопустимой комбинации.


Сначала строится НКА


N>Кто выдержит составление такой таблицы, и на каком количестве состояний генератор решит "а не пошло бы оно к бениной бабушке"?


Потом НКА приводится к ДКА.
Если такое приведение невозможно, то имеем конфликты.
Если никаких ср-в разрешения конфликтов нет, то ошибка.

Но тут есть ср-во разрешения конфликтов — сама цель регулярных выражений, например, поиск, т.е. работает ИЛИ, поэтому конфликт может выигрывать любая дуга из набора конфликтующих их.


N>Кто выдержит составление такой таблицы

N>Или я не вижу тут ещё какого-то фокуса?

Для юникода тут, действительно, слишком дофига дуг, поэтому еще с далеких первых экспериментов с парсерами на C# (там же юникод сплошной) я проводил минимизацию по терминалам в два этапа (а не в один этап, как по классике).

По классике все терминалы после минимизации ДКА разбиваются на группы, по которым происходят идентичные переходы (например, зачастую по символам 0..9).

А с юникодом пришёл к тому, что такую минимизацию имеет смысл выполнять еще на этапе составления НКА, т.е. все 64к символов схлопываются в небольшой алфавит (обычно единицы-десятки символов).

Потом опять в конце минимизация по терминалам и выведение в кодогенераторе конечной lookup-таблицы из этих двух.


V>>Просто есть же стандартные бока с левосторонней рекурсией для нисходящих парсеров, что там с этим у packrat?

N>то есть ты типа сам должен перевести рекурсию в цикл

Сам я и обычную грамматику смогу подвергнуть факторизации, но хочется этого не делать, бо левосторонне-рекурсивная запись выражений наиболее читабельна человеку (ИМХО).


V>>ANTLR сам производит факторизацию грамматики для удаления левосторонней рекурсии, в этом его главная киллер-фича, как по мне.

N>И у него явно описаны ограничения возможности этой его логики. Я бы в сложных случаях на это не залагался.

В любом случае конфликты будут обнаружены еще в процессе работы над грамматикой.


V>>А наколенный нисходящий парсер может однажды уйти в stack overflow на машине клиента. ))

N>В наколенном нисходящем... ну если его автор не протестировал

Я уже говорил — это аналогично рассуждениям о статической типизации vs динамической.
Нужного теста разработчик может быть не сможет изобрести.
А потом в продакшене классический shit happens.
Отредактировано 15.09.2020 20:01 vdimas . Предыдущая версия .
Re[8]: Написание своего DSL
От: Ночной Смотрящий Россия  
Дата: 17.09.20 13:56
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Или можно взять бизоны для LR(x)/GLR-граматик или ANTLR для LL(1).


ANTLR до 3 версии это LL(k), после LL(*)
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Написание своего DSL
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 18.09.20 11:12
Оценка:
Здравствуйте, Marty, Вы писали:

M>Точнее — парсинг и построение AST


Это не самая важная часть ДСЛ. Изначально дсл это решаемые задачи, кейсы и решения на этом языке. Как и чем ты это будешь парсить, насколько элегантным и красивым будет язык — дело вообще мало кому интересное.
Re[7]: Написание своего DSL
От: LuciferSaratov Россия  
Дата: 18.09.20 11:31
Оценка:
Здравствуйте, Marty, Вы писали:

M>Если не жалко, помоги мне поднять мой технологический уровень


щас я подниму.

способ первый: берешь "IntelliJ-based IDE" и устанавливаешь в неё https://plugins.jetbrains.com/plugin/7358-antlr-v4-grammar-plugin
после этого у тебя будет очень классно подсвечиваться грамматика, появятся инструменты для отладки грамматики, можно будет настраивать язык для генерации парсера.
удобно для освоения инструмента: умеет рисовать дерево разбора, сразу видна реакция на правки в грамматике.

способо второй: берешь Visual Studio, создаешь проект на C#, через NuGet ставишь Antlr4.4.6.6, Antlr4.CodeGenerator.4.6.6, Antlr4.Runtime.4.6.6.
грамматика тоже будет подсвечиваться, но не так классно, как в первом способе, зато antlr4 само скачает и поставит, т.е. вообще ничего больше не надо будет делать.
есть и свои удобства: сгенерированный код в проект не добавляется, но генерируется автоматически при изменении грамматики и включается в сборку.
Re[6]: Написание своего DSL
От: alexanderfedin США http://alexander-fedin.pixels.com/
Дата: 23.10.20 21:23
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Язык, на котором нельзя сказать обидную гадость, не может считаться естественным
В С++ "обидная гадость" — это либо SFINAE, либо ошибка компиляции
Respectfully,
Alexander Fedin.
Re[3]: Написание своего DSL
От: Kolesiki  
Дата: 26.10.20 16:53
Оценка:
Здравствуйте, Marty, Вы писали:

M>На высокий технологический уровень я и не претендовал, я и писал с целью вызвать дискуссию


Нафиг ты тогда пишешь СТАТЬЮ?? Ты же "никто" в этой теме! Не умнее ли задавать вопросы?
Re[4]: Написание своего DSL
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 26.10.20 20:16
Оценка:
Здравствуйте, Kolesiki, Вы писали:

M>>На высокий технологический уровень я и не претендовал, я и писал с целью вызвать дискуссию


K>Нафиг ты тогда пишешь СТАТЬЮ?? Ты же "никто" в этой теме! Не умнее ли задавать вопросы?


То есть, тебе можно писать откровенную чушь и рассовывать по всем форумам, а мне нельзя запилить статейку с описанием своего личного опыта по предлагаемой теме с приглашением к обсуждению того, где я что не так делал?
Маньяк Робокряк колесит по городу
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.