Re[24]: Хочется странного
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.02.25 02:36
Оценка:
Здравствуйте, Marty, Вы писали:

M>Это интересный вопрос, на самом деле: имхо было бы удобно описывать правила отдельно, а действия, которые производятся при матче правил — отдельно. Тогда грамматику языка можно описать один раз, а построение AST можно пилить для target языков отдельно, и биндить к правилам при выводе в целевой язык.

Это имеет смысл в ограниченном количестве случаев. Ситуации, когда одна и та же грамматика применяется для разных целевых языков, лично мне в жизни не встречались и ожиданий таковых нет.
И даже если такое встретится, мне, скорее всего, будет проще просто склонировать грамматику и переписать правила, чем мучиться с выписыванием отдельного решения.
Впрочем, если хочется попрактиковаться — именно так устроен Ohm-js. В реальности получается не особо удобно, несмотря на офигенную гибкость TypeScript. Основная проблема — безымянные части правил.
В Lingo, к примеру, я могу писать семантическия действия прямо по месту, ещё и выбирая для байндинга только нужные мне части правил:
...
Add = Term:l "+" Add:r { Sum(:l, :r}} | Term 
...

В Ohm у меня справа от = стоит безымянная альтернатива; чтобы забиндить к ней какое-то действие, нужно дать ей имя. И аргументами для действия будут все ноды, независимо от их полезности, а тип результата будет каким-то общим супертипом для всех узлов. Средства для всего этого в библиотеке есть, но выглядит костыльно:
...
Add = 
  Term "+" Add:r --two
  | Term 
...

const actions = {
  ...
  Add_two: (l, _plus, r) => Add.create(l.getAst(), r.getAst()),
  ...
} satisfies ArithmeticSemantics<AstNode>

Примерно то же самое придётся делать в более-менее любом подходе, где действия отделены от семантики. Причём ценность этого равна примерно нулю, потому что, повторюсь, целевой язык компилятора обычно известен к тому моменту, когда пишется грамматика. И лучше помочь тем, кто пилит в этом направлении, чем портить жизнь остальным 99.9% пользователей. Авторы Ohm.js приводят вырожденные примеры — типа "а давайте мы забабахаем калькулятор на семантических правилах; а теперь давайте на той же грамматике забабахаем претти-принтер". Ну вот в реальной жизни наиболее практичный способ — это не вычислять грамматикой значение выражения, а породить AST, из которого уже легко, непринуждённо, и типобезопасно получается и "вычисление значения", и pretty print, и вообще примерно всё остальное.
Особенно с учётом того, что реальные языки (в отличие от школьных примеров типа целочисленной арифметики) используют разные типы узлов в AST, и крайне полезно статически проверять корректность сборки родителей из детей.

M>Криворукий плагин не роняет фар, а просто выгружается. Хотя в фаре плагины inproc. По-моему, это тривиально делается. В винде для этого есть SEH, в других системах наверняка должно быть что-то подобное.

По-моему, вы фантазируете. Никакой SEH не поможет вам от плагина, который просто срёт в общее адресное пространство потому, что кто-то не освоил адресную арифметику, или отлаживался в дебаг-режиме, а в релизе у него неинициализированный указатель показывает в космос, а не в null.

M>Спс, я не интересовался настолько, чтобы что-то копать. LSP это конечно интересно, но вообще для VSCode есть куча плагинов на все случаи жизни, а не только для подсветки кода. Или LSP настолько всеобъемлющ, что позволяет реализовать любые типы плагинов для VSCode?

Нет, LSP — только для языковых инструментов. Плагины, которые расширяют саму студию — всякие альтернативные редакторы, интеграция юнит-тестирования или системы контроля версий пишутся на тайпскрипте и, в некотором смысле, работают in-proc. Но вас-то интересуют не они. Ну, по крайней мере мне как раз интересно, как с минимально возможными усилиями завести IDE для нового языка, а не новый пункт меню в одной случайно выбранной IDE.
M>Но да, в контексте раскраски синтаксиса и интеллисенса от LSP наверное никуда не деться.
Да, вся навигация по коду, автодополнение, signature hint, рефакторинги и всё прочее — это LSP.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.