> token Digit > token Number > Два из них, «Digit» и «Digits»
Так Number или Digits? Ниже ещё раз Number упоминается.
> Правило «s» также является специальным видом правила – void-правилом.
Предложение построено так, словно мы об этом правиле уже успели что-то прочитать.
> В лексерных правилах (помеченные ключевым словом token)
помеченныХ
> Например, если в приведенном выше правиле Number удалить использование правила «s»
А его там и нет. И без него многое в "предупреждении" на тему s и S непонятно (например: "оно все равно будет подставлено автоматически" — куда именно?). Хотя в общем это не настолько тонкий и важный для понимания идеи момент, чтобы в него вгрызаться в процессе чтения обзорной статьи.
Синтаксический модуль
> Если в правиле появилось явное использование предопределенного правила «s» (или «S»), N2 не будет ожидать явного указания пробельных символов (не будет вставлять правило «s» самостоятельно).
N2 не будет ожидать
> Правило Number является обычным (не лексерным) правилом.
NumberLiteral
> Такие правила вводят новое дерево разбора – ParseTree.
Содержащее, в том числе, значение NumberLiteral.Value, я так понимаю?
Импорт синтаксических модулей
> В ней используется правило «Number», объявленное в модуле «Literal».
NumberLiteral
Расширяемые правила
> Так как синтаксические модули являются независимыми единицами правила между ними не видны автоматически
Запятая после "единицами"
> using ExpressionPlusesExtentsion
опечатка
> using cp = Expression; // псевдоним для синтаксического модуля CalcParserExpression
опечатка
Re[2]: замечания, часть 1 (раздел "Синтаксический модуль")
Здравствуйте, dimgel, Вы писали:
>> token Digit >> token Number >> Два из них, «Digit» и «Digits» D>Так Number или Digits? Ниже ещё раз Number упоминается.
Это результаты ручного рефакторинга без тестов . Спасибо, поправлю.
Digits там было не по делу, так как это описание числа с плавающей точкой.
>> Правило «s» также является специальным видом правила – void-правилом. D>Предложение построено так, словно мы об этом правиле уже успели что-то прочитать.
Я его тоже из примера удалил. Видимо зря. Сейчас восстановлю. Просто в процессе эволюции синтаксиса исчезла декларация типов для правил. Она осталась только для void-правил. Я решил его просто спрятать, но уши остались .
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
> Для токена объявленного отдельным правилом класс
две запятых вокруг причастного оборота (или как оно там называется)
> LiteralTokenClass – описывает класс токена автоматически задаваемый всем литеральным токенам (за исключением токенам описывающим скобки). > BracketsTokenClass — описывает класс токена автоматически задаваемый всем токенам описывающим скобки.
запятые перед "автоматически" и перед "описывающим"
гаммар наци негодуэ
> Действия этих настроек распространяются на текущий синтаксический модуль и все модули в которые он импортирован. Таким образом для расширений
запятые после "все модули" и "таким образом"
> переоределить ее в текущем модуле или будет выдано сообщение
запятая перед "или"
> используется ключевое слово «brackets» за которым сделет
запятая после «brackets»
> Ниже приведен пример демонстрирующий использование
запятая после "пример"
> Подсветка кода зависит от классов токенов заданных при определении языковых конструкций.
запятая после "токенов"
> Автор этих конструкций может, как использовать предопределенные классы токенов описанные выше, так и ввести свои.
запятая после "может" — лишняя
> Для задания типа подсветки, при этом, так же используются классы токенов.
При этом, для задания типа подсветки так же используются классы токенов. (впрочем, не настаиваю)
> Конкретные цвета используемые при подсветке токенов задаются в настройках IDE.
запятые вокруг причастного оборота (или как оно там называется)
Здравствуйте, dimgel, Вы писали:
>> BracketsTokenClass — описывает класс токена автоматически задаваемый всем токенам описывающим скобки. D>запятые перед "автоматически" и перед "описывающим" D>гаммар наци негодуэ
Арфаграфия и пуктуация в новых разделах не проверялись пока . Сори.
Не надо пока на них обращать внимание. Завтра выверим, вот тогда можно будет пройтись не замыленным взглядом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Собственно опечатки — это очень хорошо. Но хотелось бы услышать критику по существу вопроса. Насколько понятно получилось? VD>Какие вопросы остаются после прочтения?
Ну я ещё не дочитал, а уже как минимум один вопрос, разжёванный ниже, успел задать.
Вопросы в основном проистекают из-за незнакомого синтаксиса. Если пытаться мотать на ус, а не просматривать типа фельетончик в общих чертах, то вот тут, например:
syntax NumberLiteral = number
{
where number : Number;
Value : decimal = decimal.Parse(GetText(number));
}
Я так и не понял сакральный смысл того, что "number" тут дублируется в первой строке и в where. В where, как я понял, объявляется тип подправила и типы полей. Но чем именно является "number"? Ты пишешь: "будет создан тип NumberLiteral с полем number типа Number и Value типа decimal". Следовательно, number — это поле. А что тогда оно делает в первой строке после "NumberLiteral = "?
Здравствуйте, dimgel, Вы писали:
>> Такие правила вводят новое дерево разбора – ParseTree. D>Содержащее, в том числе, значение NumberLiteral.Value, я так понимаю?
Да об этом говорится позже. ОК, добавил это для ясности.
D>Импорт синтаксических модулей
>> В ней используется правило «Number», объявленное в модуле «Literal». D>NumberLiteral
Сенкс.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
D> syntax NumberLiteral = number
D> {
D> where number : Number;
D> Value : decimal = decimal.Parse(GetText(number));
D> }
D>
D>Я так и не понял сакральный смысл того, что "number" тут дублируется в первой строке и в where. В where, как я понял, объявляется тип подправила и типы полей.
Не совсем так. В "where" указывается подправило грамматики ассоциируемое с параметром. А уже сама грамматика определяет тип поля.
Это описывается ниже. Мне кажется, для чистоты эксперимента надо дочитать до конца.
D>Но чем именно является "number"?
Именем поля.
У нас две задачи.
1. Описать подправило грамматики.
2. Дать ему имя.
Сейчас, кстати, это делается по другому. В теле правила всегда описывается чистая грамматика, а имена задаются в атрибуте Ast().
Проблема этого подхода заключается в том, что имена приходится задавать позиционно. Это довольно неудобно и приводит к массе ошибок. Особенно при рефакторинге.
D>Ты пишешь: "будет создан тип NumberLiteral с полем number типа Number и Value типа decimal". Следовательно, number — это поле. А что тогда оно делает в первой строке после "NumberLiteral = "?
Определяет грамматику. С полем ассоциируется не тип, а подправило грамматики. Тип поля автоматически выводится из описания подправила. Например, если подправило это ссылка на другое именованное правило, то типом поля будет тип этого правила (совпадает с именем правила). Если же это цикл "SomeRule*", то тип будет list[SomeRule].
Если не ошибаюсь — это тоже описано ниже.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
http://stdray.livejournal.com/65441.html?thread=292513#t292513:
>Есть вопросы.
> 1) В гайде ты упоминал, что инструкции, написанные внутри блока scope {}, прозрачно применяются, когда мы входим в блок, и отменяются, когда мы из него выходим. Прозрачно отменяются? Это как?
При выходе из внешнего скопа закрывается и вложенный. При закрытии скопа все его настройки автоматически теряются и начинают действовать настройки внешнего скопа.
> 2) Можно ли механизмом публикации символов реализовать области видимости для параметров по умолчанию, а именно что-то типа: > def foo(x: Int, y: Int = x * x) = ??? // компилируется > def bar(x: Int, y: Int = z * z, z: Int = 42) = ??? // ошибка
Такой порядок будет по умолчанию. Вот если не хочется, чтобы параметры были доступны при описании других параметров, то нужно будет указать, что их скопы распространяются только на тело функции.
> 3) Можно ли в текущей модели символов сделать имплиситы, а именно: > class Foo > class Bar { def bar = ??? } > implicit def foo2bar(foo: Foo) = new Bar > new Foo().<...> > ><...> должен увидеть bar
Можно. Но это уже будет действовать механизм типизации куда интегрируется механизм разрешения перегрузки.
>4) Можно ли в текущей модели типов реализовать higher-kinded полиморфизм?
Систему типов ты описываешь сам (если не используешь предопределенную). Типизацию — тоже. Так что что опишешь то и будет.
Вопрос только на фиг оно надо? Ну, второго порядка еще куда не шло. А н-ного — перебор, по-моему. В прочем, если есть нужда...
>Экзистенциальные типы? Зависимые типы? Пересечения и объединения? null-safety цейлоновской мощности?
Да нам что? Вы определяете как типы будут унифицироваться. Если в результате унификации два типа дадут пересечение, то будете с ним возиться. Вопрос только во что вы его в последствии преобразуете (когда будете код генерировать).
И вообще, наша задача подогнать модель под реальные потребности, а не заставить всех натягивать свои потребности на имеющиеся возможности. По сему если даже мы что-то не учтем по первой, то поправим потом.
>5) Можно ли реализовать erasure, например, для юзкейса, описанного в треде выше?
Если я правильно понял что ты хочешь, то в N2 этого просто не нужно. В исходном языке типы такие какие они есть и не нужно их удалять/стерать. А вот кода ты пишешь преобразование в язык более низкого уровня, то ты вполне можешь опустить подробности и сгенерировать более простой тип или более общий.
>6) Аналогичный вопрос про специализацию полиморфных типов для ситуаций, когда рантайм-специализация неприемлема или недоступна.
Мы просто не оперируем такими понятиями. Мы предоставляем общий механизм типизации который можно настраивать под язык. Правила описания типов в своем языке ты задаешь сам. То во что этот код потом развернется тоже задаешь ты сам.
>7) Как планируется реализовывать интеграцию в IDE? Есть ли на эту тему информация?
Есть. И если читать внимательно, то не трудно ее заметить .
>Особенно интересует скорость отклика.
Ну, мы постараемся чтобы было по шустрее. Можете нам помочь в этом плане исследованиями.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Про систему типов понятно. Я думал, что-то опущено в тексте статьи, но теперь вроде ясно — просто есть максимально общий фреймворк. Отлично.
Насчет IDE я потому и спросил, что в статье только конспективно. Интересно было бы узнать подробности. Скажем, нажимаю я ctrl+space. Что происходит дальше?
Здравствуйте, xeno.by, Вы писали:
XB>Насчет IDE я потому и спросил, что в статье только конспективно. Интересно было бы узнать подробности. Скажем, нажимаю я ctrl+space. Что происходит дальше?
Получаешь дополнение текущего символа.
Технически проходит парсинг в специальном режиме. В нем отслеживается позиция курсора и если в ней находится некий символ, то он обрабатывается специальным образом. Если в обычном режиме мы пытаемся найти полное соответствие символа, то в этом мы ищем префикс, подстроку (определяется функцией фильтрации) или некий другой символ (например, точку в ООЯ). Далее, если найден ровно один символ, то мы его молча комплитим. Если найдено несколько символов, мы создаем список комплита как сумму всех возможных значений символа.
Возможно в грамматике придется описать места возможного комплита. Это уже детали которые надо будет продумать по глубже.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Если в обычном режиме мы пытаемся найти полное соответствие символа, то в этом мы ищем префикс, подстроку
То есть, получается, мы ищем по таблице символов? А что если автокомплит включает в себя тайпчек (как с имплиситами)?
Еще вот сегодня Женя Кирпичев запостил свои впечатления об ADD: http://antilamer.livejournal.com/431555.html, где упомянул, что в чем-то N2 и MPS похожи. Я про MPS знаю только понаслышке, поэтому было бы интересно услышать подробности — где похожи, где отличия.
Здравствуйте, xeno.by, Вы писали:
VD>>Если в обычном режиме мы пытаемся найти полное соответствие символа, то в этом мы ищем префикс, подстроку XB>То есть, получается, мы ищем по таблице символов?
Не только. Разрешение типов тоже нужно производить. Это на всех стадиях работает. Фактически в стандартную процедуру вводятся "закладки" которые перехватывают обработку в нужный момент.
XB>А что если автокомплит включает в себя тайпчек (как с имплиситами)?
Он по любому включает. Скажем если мы комплитим
x.y.z|
то перед тем как закомплитить z нам нужно вычислить что такое y.
Но тут проблема в том, что и x и y могут сами по себе быть перегруженными, так что для них нужно вычислять все перегрузки, а z искать внутри них (всех).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, xeno.by, Вы писали:
XB>Еще вот сегодня Женя Кирпичев запостил свои впечатления об ADD: http://antilamer.livejournal.com/431555.html, где упомянул, что в чем-то N2 и MPS похожи. Я про MPS знаю только понаслышке, поэтому было бы интересно услышать подробности — где похожи, где отличия.
Если честно, я тоже об МПС знаю только понаслышке. Я вообще не Явский человек.
Надо будет поставить посмотреть.
Судя по этому ролику. Похожего действительно много. Ну, а главное различие — это то что в МПС отказались от текста и предлагают писать программы в формах ввода. Мы же на против считаем, что код — это в первую очередь текст. Я должен иметь право работать с ним как хочу.
Ну, и конечно же в МПС нет понятия макроса. Они не дают манипулировать АСТ программы (если я все правильно понял). Мы же, как немерловые люди, хотим получить систему которая это предоставляет. Соответственно продумываем эти возможности.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
XB>>Еще вот сегодня Женя Кирпичев запостил свои впечатления об ADD: http://antilamer.livejournal.com/431555.html, где упомянул, что в чем-то N2 и MPS похожи. Я про MPS знаю только понаслышке, поэтому было бы интересно услышать подробности — где похожи, где отличия.
VD>Ну, и конечно же в МПС нет понятия макроса. Они не дают манипулировать АСТ программы (если я все правильно понял). Мы же, как немерловые люди, хотим получить систему которая это предоставляет. Соответственно продумываем эти возможности.
Не совсем так. Скорее уж весь MPS это один сплошной макрос. Мы определяем типы синтаксических узлов и для них определяем: форму отображения в редакторе, правила типизации, правила dataflow, правила scoping, правила трансформации в другой AST или прямо в конечный текст, правила для отладчика... Например, джавские узлы трансформируются прямо в текстовый исходник на джаве. А надстройки (например, лямбда-литералы и пр.; я вот делал монаду асинхронности тоже) трансформируются в джавские узлы или в другие надстройки.
Притом MPS "метациклический", т.е. все эти правила также описываются в MPS-овских редакторах и их синтаксис и семантика описаны на MPS.
Если есть еще какие-то вопросы, могу Вас связать с людьми из команды MPS.
Здравствуйте, jkff, Вы писали:
VD>>Ну, и конечно же в МПС нет понятия макроса. Они не дают манипулировать АСТ программы (если я все правильно понял). Мы же, как немерловые люди, хотим получить систему которая это предоставляет. Соответственно продумываем эти возможности.
J>Не совсем так. Скорее уж весь MPS это один сплошной макрос.
Этак можно про любой язык сказать.
J>Мы определяем типы синтаксических узлов и для них определяем: форму отображения в редакторе, правила типизации, правила dataflow, правила scoping, правила трансформации в другой AST или прямо в конечный текст, правила для отладчика...
Да я как бы и так это все понял. Но это все совершенно не то. МПС средство для создания нерасширяемых языков.
Понимаю, что звучит это странно, но похоже это так. МПС не предполагает трансформацию программ. И тем более не предполагает трансформацию программ в самих в себя.
Попробую объяснить смысл сказанного мной выше. Возьмем к примеру макро-атрибуты. Классическим примером, пожалуй, является макрос Record.
1. Этот макрос не имеет какого-то своего синтаксиса. Он имеет синтаксис пользовательского атрибута применяемого к типам. Если в области видимости открыто пространство имен в котором объявлен макрос, то выбирается макрос. Иначе производится поиск аналогичного атрибута.
2. Этот макрос формирует конструкцию (конструктор) того же самого языка. Причем делает это на основании списка полей класса и других макро-атрибутов примененных к ним (атрибутов RecordIgnore).
3. Конструкторы генерированные макросом влияют на процесс типизации выражений.
4. Макросы действуют не по одиночке, а зависят друг от друга. Другие макросы могут генерировать поля, что может влиять на работу макросов генерирующих конструкторы по полям и так далее.
Я ночью поглядел МПС. Заметил там какое-то наличие ручного манипулирования АСТ, но мне кажется, что это вряд ли моно рассматривать как штатное средство. Да и почти уверен, что геморрой с зависимостями в МПС не разрулить.
J>Например, джавские узлы трансформируются прямо в текстовый исходник на джаве. А надстройки (например, лямбда-литералы и пр.; я вот делал монаду асинхронности тоже) трансформируются в джавские узлы или в другие надстройки.
Это я и так понимал, но это не то. Этого мало.
J>Притом MPS "метациклический", т.е. все эти правила также описываются в MPS-овских редакторах и их синтаксис и семантика описаны на MPS.
Это все тоже понятно.
Я покапал МПС этой ночью. Многие идеи похожи. Много общего. Но недостатков в их подходе не мало. Я потратил 4 часа на воспроизведение банального if-а. На Nemerle 1.х или на N2 у меня на это ушло бы менее минут.
Понятно, что у меня не было опыта использования МПС. Но все же я знаком со всеми необходимыми концепциями и просмотрел множество материала. Так что по идее за пол часа я должен был бы справиться.
Кроме того редактор на основе форм переодически просто бесит. Если неудобство еще можно терпеть, то исчезновении информации при редактировании — это пипец! Возникает желание швырнуть ноут в стену .
J>Если есть еще какие-то вопросы, могу Вас связать с людьми из команды MPS.
Спасибо. Я думаю, что мы с ними по любому свяжемся. С кое-кем из ДжетБрэйнса я знаком. Но не с теми кто работает над МПС.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Еще пару вопросов:
1) Как дебагать тайпчекер написанный на N2?
2) Как планируется структурировать такие тайпчекеры? Есть ли планы предоставить что-то большее, чем абстрактный фреймворк? Есть ли какие-нибудь кейс стади на эту тему? Меня очень заинтересовала тема генераторов тайпчекеров, поэтому познавательно было бы узнать, чего здесь можно достичь.
RuleName – имя правила. Для него создается вложенный (в модуль) класс. Этот класс наследуется от класса с именем RuleNameBase. Это сделано, так как кроме класса, представляющего дерево разбора N2, также генерирует классы RuleNameError и RuleNameSplice для представления ошибок в коде и для представления квази-цитат.
Непонятно. Так почему же всё таки класс наследуется от RuleNameBase? То ли RuleNameError и RuleNameSplice тоже наследуются от RuleNameBase, то ли просто так карты лягли?
using cp = Expression; // псевдоним для синтаксического модуля CalcParser
Видимо имелось ввиду Expression.
Если при используется отношение подтипа, основанное на наличии неявного применения типов, то информация об этом записывается в конкретизируемую переменную типов. Его можно использовать на стадии трансформации кода для вставки кода преобразующего типы. Можно делать проверки и, например, не допускать использование неявных приведений типов.
Здравствуйте, fddima, Вы писали:
F>Здравствуйте, VladD2, Вы писали:
F>
RuleName – имя правила. Для него создается вложенный (в модуль) класс. Этот класс наследуется от класса с именем RuleNameBase. Это сделано, так как кроме класса, представляющего дерево разбора N2, также генерирует классы RuleNameError и RuleNameSplice для представления ошибок в коде и для представления квази-цитат.
F> Непонятно. Так почему же всё таки класс наследуется от RuleNameBase? То ли RuleNameError и RuleNameSplice тоже наследуются от RuleNameBase, то ли просто так карты лягли?
Первое. В прочем, это детали реализации. На сегодня они отличаются. Так что можно это просто игнорировать.
F>
using cp = Expression; // псевдоним для синтаксического модуля CalcParser
F>Видимо имелось ввиду Expression.
Да. Это баг. Я его уже поправил. Но документ пока не обновил.
F>
F>Если при используется отношение подтипа, основанное на наличии неявного применения типов, то информация об этом записывается в конкретизируемую переменную типов. Его можно использовать на стадии трансформации кода для вставки кода преобразующего типы. Можно делать проверки и, например, не допускать использование неявных приведений типов.
Спасибо! Подправил.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Да, почитал, половину, наверное ещё мозгом не осознал, со скопами вообще каша образавалась не понял — но всё вместе выглядит очень интересно. Попробовать бы уже поскорее.
Здравствуйте, fddima, Вы писали:
F>Да, почитал, половину, наверное ещё мозгом не осознал, со скопами вообще каша образавалась не понял — но всё вместе выглядит очень интересно. Попробовать бы уже поскорее.
Пока только парсер. Но он крут как вареное яйцо. За что отдельное благодарность WolfHound-у. Пример что я приводил как раз на нем сделан. Только он пока в несколько другом синтаксисе. Поля определяются в атрибуте Ast.
Собственно присоединяйся. Тем самым сократишь сор появления сия чуда.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Пока только парсер. Но он крут как вареное яйцо. За что отдельное благодарность WolfHound-у. Пример что я приводил как раз на нем сделан. Только он пока в несколько другом синтаксисе. Поля определяются в атрибуте Ast. VD>Собственно присоединяйся. Тем самым сократишь сор появления сия чуда.
Да в общем-то даже парсер интересен и без типизации и прочих чудес. Первая половина статьи расказывает как описывать разные не очень сложные вещи с синтаксисом не вырывающим глаза — толковых аналогов (опускаем алгоритм парсера) — не видел — и мне это очень понравилось. А в целом — хотелось бы просто вменяемого тулсета, и у N2 судя по описанию да и вообще разговорам на форуме — есть все шансы таким стать. Да и возможности несравнимые...
Вливаться — не знаю как — задач уйма помимо основной работы. Так что не вижу как я бы смог принести пользу, кроме того с N, всё же не знаком — особо ярых проблем с понимаем N не вызывает, но всё же на нём я ничего не писал. + пока, что та задача для которой бы сгодился DSL — уже выполнена, но тупо через XML. Неудобно. Но переписывать пока что смысла нет — после отладки эта модель более меняться не будет.
Но переделать ради домашнего задания, — для меня лично был бы наилучший практический пример.
Но в будущем я вижу необходимость ещё 1-3 DSL, — хотя как карта ляжет.
Поэтому если уже можно как-то пощупать минимальный функционал N2... было бы интересно.
Здравствуйте, fddima, Вы писали:
F> Да в общем-то даже парсер интересен и без типизации и прочих чудес. Первая половина статьи расказывает как описывать разные не очень сложные вещи с синтаксисом не вырывающим глаза — толковых аналогов (опускаем алгоритм парсера) — не видел — и мне это очень понравилось.
Сейчас синтаксис немного иной. Поля описываются атрибутом Ast перед правилом. А в правиле идут только ссылки на другие правила и т.п. Читается он тоже не плохо. Писать немного не удобно, так как когда полей становится много, то начинаешь путаться. Но скоро мы это дело приведем к синтаксису описанному в статье.
F>А в целом — хотелось бы просто вменяемого тулсета, и у N2 судя по описанию да и вообще разговорам на форуме — есть все шансы таким стать.
N2 задуман как интегрированное решение, но в приципе его можно использовать и по частям. Так генератор парсеров, в конце концов, генерирует банальный набор классов. Класс парсера и классы описывающие АСТ. Если есть желание, то с ними можно работать и вручную (на сегодня только вручную).
F>Да и возможности несравнимые...
Это да. Собственно на то и расчет, чтобы крутые возможности были скрыты за максимально простыми в использовании языками.
F> Вливаться — не знаю как — задач уйма помимо основной работы.
Дык все кто работал над Немерлом, и работают над N2 тоже имеют свои задачи. Если не найдем инвестора, то придется работать над проектом выделяя время отрывая его от других задач.
F>Так что не вижу как я бы смог принести пользу, кроме того с N, всё же не знаком — особо ярых проблем с понимаем N не вызывает, но всё же на нём я ничего не писал.
Все когда-то начинали. Через неделю втягиваешся и не понимаешь как мог программировать на чем то другом.
Я когда первый раз на немерле попрограммировал с месяц, потом ощутил дикую ломку когда обратно за шарп взялся.
F> Но переделать ради домашнего задания, — для меня лично был бы наилучший практический пример.
Тоже дело. В парсере хотя логика и работает, но еще не мало шероховатостей которые нужно выявлять и шлифовать. Так что свежий глаз сам по себе полезен.
F> Но в будущем я вижу необходимость ещё 1-3 DSL, — хотя как карта ляжет.
Тем более.
F> Поэтому если уже можно как-то пощупать минимальный функционал N2... было бы интересно.
Современная версия парсера доступна здесь. Для ее использования нужен свежаший вариант компилятора который лучше собрать из исходников, или, по крайней мере, взять из ночных сборок.
В проекте есть примеры. Изучать возможности нужно по ним. Если есть какие-то вопросы, то можно сюда задавать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, xeno.by, Вы писали:
XB>Еще пару вопросов: XB>1) Как дебагать тайпчекер написанный на N2?
Учитывая, что для вывода типов будет использоваться констрэйн-солвер — это не простой вопрос. Думаю, что мы сможем предоставить логи солвера. Можно сделать режим при котором неудачная унификация будет приводить к запуску отладчика или выводу некоторого отладочного ГУЙя.
XB>2) Как планируется структурировать такие тайпчекеры? Есть ли планы предоставить что-то большее, чем абстрактный фреймворк? Есть ли какие-нибудь кейс стади на эту тему? Меня очень заинтересовала тема генераторов тайпчекеров, поэтому познавательно было бы узнать, чего здесь можно достичь.
Код связанный с проверкой типов будет генерироваться по описанию. Не смотря на расширения и всевозможные выверты в системе типов, в основе все равно будет лежать граф типов и система унификации переменных типов в нем.
По сути, если взглянуть на рукописаный тап-чекер, то это тупой код бегающий по АСТ и связывающий между собой типы разных выражений (унифицирующий переменные предоставляющие эти типы). Если унификация удается, то делаются следующие проверки, если нет, то код пытается выбрать другой путь. По сути есть набор вариантов которые проходят или не проходят. Конечный результат — это такое состояние графа типов где на все типы наложены ограничения и они не противоречат друг другу.
Декларативное описание позволяет задать структур этого алгоритма и сгенерировать эффективный код по нему.
Собственно самая сложная част — это разрешение перегрузок. Здесь очень легко получить экспоненциальный рост переборов. Здесь нужны эвристики. Думаю, что мы предоставим подобные вещи из коробки и дадим людям настраивать мелкие детали.
В общем, это еще открытое поле для исследования. У нас есть прототип в виде рукописного тайпчекера немерла. Но эксперементов в этой области еще придется сделать не мало. Сейчас ясно только, что задача принципиально решаемая. И ясны общие пути ее решения.
Если хочешь, присоединяйся.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Это все интересно, но пока только теория, все же хочется многое пощупать, как это работает и как удобно этим пользоваться. В процессе разработки проекта могут возникнуть разные трудности реализации тех идей, которые запланированы, вот лучше ближе к этому как привести все это в реальность. До конечного релиза все может серьезно поменяться, но как теоретическая база сгодиться.
Здравствуйте, VladD2, Вы писали:
VD>В проекте есть примеры. Изучать возможности нужно по ним. Если есть какие-то вопросы, то можно сюда задавать.
Что лучше использовать? https://github.com/rampelstinskin/ParserGenerator или https://github.com/rsdn/ParserGenerator — последний вроде чуток иногда отстаёт.
Примеры... ну понятно, всё что .n2 уже пример. Пока разбираюсь, пробую заюзать — с не привычки идёт туго. Интеграция показывает ерунду всяку. Впрочем... пошел качать ночную сборку.
Project overview нигде не нашел...
Что такое ExternalGrammar — для чего планируется?
N2Parser, N2ParserExtensions — а это для чего?
N2VsExtentions — есть ли там что-то работающее, стоит ли это пробовать?
ЗЫ: Как и говорил, решил потренироваться на "кошках", единственно, что внесу новых плюшек в свой генератор. Поскольку работать с получаемым AST в чистом виде вроде бы как и не очень удобно — хочется преобразовать в своё внутреннее представление. Правильно ли это, и есть ли какие-нибудь хорошо зарекомендовавшие себя техники для этого? Для моей задачи — в 90% будет более-менее тупое перебрасывание из AST в мою модель, ну правда там есть некоторое связывание, и некоторая доля преобразований (когда я генерирую сериализатор — мне проще работать с плоским набором полей, а не иерархией классов и разбираться где declared-only поля, а когда генерирую модели — наоборот, важны декларации).
ЗЗЫ: А можно ли генерировать классы из макросов с xmldoc-комментариями?
Здравствуйте, fddima, Вы писали:
F> Что лучше использовать? https://github.com/rampelstinskin/ParserGenerator или https://github.com/rsdn/ParserGenerator — последний вроде чуток иногда отстаёт.
В данный момент их лучше вообще не использовать.
Ибо данный проект находится в очень не стабильной фазе.
И ломающие изменения случаются регулярно и без предупреждений.
F> Project overview нигде не нашел... F> Что такое ExternalGrammar — для чего планируется? F> N2Parser, N2ParserExtensions — а это для чего? F> N2VsExtentions — есть ли там что-то работающее, стоит ли это пробовать?
Это все тестовые проекты.
F> ЗЫ: Как и говорил, решил потренироваться на "кошках", единственно, что внесу новых плюшек в свой генератор.
В какой свой?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>В данный момент их лучше вообще не использовать. WH>Ибо данный проект находится в очень не стабильной фазе. WH>И ломающие изменения случаются регулярно и без предупреждений.
Ну это не страшно. Резко новые версии можно ж и не брать.
F>> ЗЫ: Как и говорил, решил потренироваться на "кошках", единственно, что внесу новых плюшек в свой генератор. WH>В какой свой?
Я где-то здесь описывал, сейчас не вижу где. Есть генератор моделей и генератор сериализатора/десериализатора со своими особенностями. Исходная модель описана в XML. Вот на этих "кошках" в рамках домашнего задания и инетересно поразбираться.
Основной репозиторий https://github.com/rampelstinskin/ParserGenerator. Но использовать его для чего-то серьезного не стоит. Он будет существенно переделвываться. Причем не только реализация, но и синтаксис.
Если сейчас что-о нужно отпарсить, то используй Nemerle.Peg из поставки.
F> Project overview нигде не нашел...
. Но, сам понимаешь, сейчас большую часть описанного не воспроизвести. Да и изменится все по ходу дела.
F> Что такое ExternalGrammar — для чего планируется?
Детали реализации. На них вообще смотреть не надо. Все еще 100 раз изменится.
F> N2Parser, N2ParserExtensions — а это для чего?
Это зачаток примера изменяемого языка. Грубо говоря описание немерла в зачаточном виде. Там можно наблюдать динамическую загрузку грамматики.
F> N2VsExtentions — есть ли там что-то работающее, стоит ли это пробовать?
Кое как подсвечивает код для описанных языков. В принципе работает. Но это пока очень примитивный прототип. Опять таки со временем изменится очень сильно. Смотреть на него особого смысла нет.
F> ЗЫ: Как и говорил, решил потренироваться на "кошках", единственно, что внесу новых плюшек в свой генератор. Поскольку работать с получаемым AST в чистом виде вроде бы как и не очень удобно — хочется преобразовать в своё внутреннее представление.
Вообще-то работать с получаемым АСТ довольно удобно. Делать какой-то свой самопал точно смысла нет. Но в дальшейшем планируется, что с голым АСТ никто дело иметь не будет. Да и самого АСТ может не быть вовсе.
F>Правильно ли это, и есть ли какие-нибудь хорошо зарекомендовавшие себя техники для этого? Для моей задачи — в 90% будет более-менее тупое перебрасывание из AST в мою модель, ну правда там есть некоторое связывание, и некоторая доля преобразований (когда я генерирую сериализатор — мне проще работать с плоским набором полей, а не иерархией классов и разбираться где declared-only поля, а когда генерирую модели — наоборот, важны декларации).
Ты смотришь на совсем зачаточную стадию. Говорить о каких-то практиках просто невозможно. Единственное что можно гарантировать, что все это очень сильно изменится.
Так что воспринимай это на раннюю демонстрацию будущих возможностей. А не как на продукт с недокументированным АПИ.
F> ЗЗЫ: А можно ли генерировать классы из макросов с xmldoc-комментариями?
В будущем будет можно. Пока что там еще ничего по этому поводу не сделано.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
F>> ЗЫ: Как и говорил, решил потренироваться на "кошках", единственно, что внесу новых плюшек в свой генератор. Поскольку работать с получаемым AST в чистом виде вроде бы как и не очень удобно — хочется преобразовать в своё внутреннее представление. VD>Вообще-то работать с получаемым АСТ довольно удобно. Делать какой-то свой самопал точно смысла нет. Но в дальшейшем планируется, что с голым АСТ никто дело иметь не будет. Да и самого АСТ может не быть вовсе.
"Расширяя" его под свои нужды? (Рассматривая случай пока АСТ есть, конечно же). Вроде как-то делалось, если не изменяет память.
VD>Если сейчас что-о нужно отпарсить, то используй Nemerle.Peg из поставки. VD>Ты смотришь на совсем зачаточную стадию. Говорить о каких-то практиках просто невозможно. Единственное что можно гарантировать, что все это очень сильно изменится. VD>Так что воспринимай это на раннюю демонстрацию будущих возможностей. А не как на продукт с недокументированным АПИ.
Ну как я писал выше — мне оно не горит... Но поковырять не отказался бы. Тем более этот опыт нужен, что бы позже сделать уже нечто нужное. Иначе говоря — стоит ли ждать именно N2, или нет, — вот в чём вопрос. И какими эти тулзы будут...
Какая-то резкая смена позиции, — то всех зазывал, теперь говоришь юзай N.Peg и не парься. Не понимаю.
F>> ЗЗЫ: А можно ли генерировать классы из макросов с xmldoc-комментариями? VD>В будущем будет можно. Пока что там еще ничего по этому поводу не сделано.
Я ещё на примере DbImport увидел, что было бы неплохо иметь возможность в большей мере "подсказать" интеллисенсу / помощь в генерации документации. Но на самом деле и без этого можно обойтись / решить по другому.
Здравствуйте, fddima, Вы писали:
F> Какая-то резкая смена позиции, — то всех зазывал, теперь говоришь юзай N.Peg и не парься. Не понимаю.
Я просто оберегаю тебя от напрасного труда. Если поиграть, то не вопрос. Но если ты что-то серьезное хочешь делать, то стоит немного подождать, так как как раз в ближайшее время предстоят серьезные переделки.
F> Я ещё на примере DbImport увидел, что было бы неплохо иметь возможность в большей мере "подсказать" интеллисенсу / помощь в генерации документации.
Согласен. Надо будет подумать как это дело сделать по удобнее. В Немерле очень этого не хватает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
F>> Какая-то резкая смена позиции, — то всех зазывал, теперь говоришь юзай N.Peg и не парься. Не понимаю. VD>Я просто оберегаю тебя от напрасного труда. Если поиграть, то не вопрос. Но если ты что-то серьезное хочешь делать, то стоит немного подождать, так как как раз в ближайшее время предстоят серьезные переделки.
Понял. Спасибо.