[N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.09.11 02:06
Оценка:
Привел статью посвященную синтаксическим макросам Н2 в соответствие с текущим их пониманием.

Думаю, что теперь она должна более полно и внятно отражать их суть.

Приветствуется любая критика.

ЗЫ

Сразу оговорюсь, что в данной статье намеренно опускается рассуждения о типизации. Они будут описаны тут (позже).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [N2] Синтаксические макросы
От: catbert  
Дата: 25.09.11 08:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Приветствуется любая критика.


1.

syntax "if" "(" cond ")" e1 ";"? "else" e2


Зачем ";"? Ведь в Немерле-1 к любому выражению и так можно приписать ; без последствий.

2. Почему бы не дать каждому виду макросов свое имя? Например, оставить macro для самого популярного вида: тех, которые расширяют другие макросы. Расширяемые макросы типа Expr назвать macrobase, или там choice, или extensible.

3. Я так и не понял, во что в конечном итоге переписываются макросы. В Nemerle 1 с этим просто — MacroCall переписывается в PExpr. Но в Nemerle 2 нету никакого PExpr! Есть только Expr, который сам по себе макрос.
@?. переписывается в if, if переписывается в match, но match тоже Expr. Что с ним-то делать?

4. Мне кажется, не стоит называть дерево разбора Ast. AST означает Abstract syntax tree — важное понятие для авторов языка, и непонятную белиберду для пользователей. Им вряд ли интересно, что такое ast, почему оно abstract и так далее.

Это как с лямбдами. Почему они лямбды? Кому интересно, что их прародитель — λ-исчисление какого-то древнего дядьки? Название "анонимные функции" понятнее.

В данном случае, проще и правильнее назвать класс просто Code.
Re[2]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.09.11 13:46
Оценка:
Здравствуйте, catbert, Вы писали:

C>Зачем ";"? Ведь в Немерле-1 к любому выражению и так можно приписать ; без последствий.


Сдирал грамматику с макроса из Nemerle 1. Зачем-то в ней ";"? присутствует. Даже не задумывался зачем.

C>2. Почему бы не дать каждому виду макросов свое имя? Например, оставить macro для самого популярного вида: тех, которые расширяют другие макросы. Расширяемые макросы типа Expr назвать macrobase, или там choice, или extensible.


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

C>3. Я так и не понял, во что в конечном итоге переписываются макросы. В Nemerle 1 с этим просто — MacroCall переписывается в PExpr. Но в Nemerle 2 нету никакого PExpr! Есть только Expr, который сам по себе макрос.

C>@?. переписывается в if, if переписывается в match, но match тоже Expr. Что с ним-то делать?

Каждый макрос вводит новый тип описывающий АСТ. Полями такого типа становятся аргументы макроса. Даже если у макроса есть тело, при парсинге сначала формируется АСТ верхнего уровня. MacroCall больше не будет, так как для любого макроса будет полноценное АСТ.

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

C>4. Мне кажется, не стоит называть дерево разбора Ast. AST означает Abstract syntax tree — важное понятие для авторов языка, и непонятную белиберду для пользователей. Им вряд ли интересно, что такое ast, почему оно abstract и так далее.


Ну, а как его называть? Можно назвать PerseTree. Но это длинно и ничего не меняет.

C>Это как с лямбдами. Почему они лямбды? Кому интересно, что их прародитель — λ-исчисление какого-то древнего дядьки? Название "анонимные функции" понятнее.


С лямбдами, как раз, название прижилось и всем уже по фигу почему они так называются. На сегодня почти никто не использует термины вроде анонимной функции. Или используют для недосинтаксиса C# появившегося в версии 2.0.

C>В данном случае, проще и правильнее назвать класс просто Code.


Это вообще не отражает сути. Название должно отражать суть, а не быть бессмысленным тегом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [N2] Синтаксические макросы
От: Аноним  
Дата: 26.09.11 04:41
Оценка:
<[ TypeDeclaration.Class:
$atts $mods $partial class $name $typeParams $parents $constraints { $members }
]>

<[ Class:
$atts public $partial class $name $typeParams $parents $constraints { $members "}"
]>

<[ Class:
abstract class MyClass : ..$parents "{" $members "}"
]>

тут вроде что то не так с кавычками
Re: [N2] Синтаксические макросы
От: Дьяченко Александр Россия  
Дата: 26.09.11 14:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Привел статью посвященную синтаксическим макросам Н2 в соответствие с текущим их пониманием.


VD>Думаю, что теперь она должна более полно и внятно отражать их суть.


lass = attributes? modifiers? "partial"? "class" identifier type-parameter-list?  
          class-base? type-parameter-constraints-clauses? body ";"?


В выделенном месте навено должно быть class.
... << RSDN@Home 1.2.0 alpha 5 rev. 1536>>
Re[2]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.09.11 16:10
Оценка:
Здравствуйте, Дьяченко Александр, Вы писали:

ДА>В выделенном месте навено должно быть class.


Да. Спасибо! Поправил.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.09.11 16:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А><[ Class:

А> abstract class MyClass : ..$parents "{" $members "}"
А>]>

А>тут вроде что то не так с кавычками


Ага. Поправил. Спасибо!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: [N2] Синтаксические макросы
От: Ziaw Россия  
Дата: 26.09.11 18:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Привел статью посвященную синтаксическим макросам Н2 в соответствие с текущим их пониманием.


macro Class is TypeDeclaration
почему не
macro Class : TypeDeclaration
второе сильно понятнее и следует семантике :. Расширяет это другие макросы или нет, компилятор может вычислить самостоятельно. Для самого макроса это может быть абсолютно не важно, он самодостаточен.

Контринтуитивно
macro TypeDeclaration;

Как минимум abstract macro, а лучше что нибудь типа: extension point и sealed extension point.

Понятно как расширяет аст макрос без тела, непонятно как это делать в теле.

Непонятно что такое @::, если функция, нужно это объяснить и приделать юзинг.

про лишние кавычки в
  $atts public $partial class $name $typeParams $parents $constraints { $members "}"

уже писали, но видимо снова пропущены.

Двоеточие для приоритетов — неконсистентный стиль. Лучше ключевое слово, в крайнем случае другой смайлик (например обычные скобки, syntax expr1(11) "::" expr2(10)). Хотя экономить символы тут глупо, таких макросов минимум.

Химия с созданием одноименных типов и вариантов внутри класса сложна для понимания и будет вызывать ступор. Один и тот же идентификатор в разных областях видимости указывает на очень разные сущности.

Этот код вызывает разрыв шаблона
macro PartialModifier : Ast[bool]


Ast[bool] это что? Аст из любого типа? Что мешает сделать его просто bool?
Re[2]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.09.11 19:53
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>
macro Class is TypeDeclaration
почему не
macro Class : TypeDeclaration
второе сильно понятнее и следует семантике :. Расширяет это другие макросы или нет, компилятор может вычислить самостоятельно. Для самого макроса это может быть абсолютно не важно, он самодостаточен.


Потому что ":" тоже используется для указания типа в случае наличия тела.

Это конечно вопрос дискуссионный. Пока я вижу это так.

Кроме того синтаксис взять из новой версии PegGrammar (которую Вольфхаунд уже пол года не может дописать). Там is используется для расширения других макросов (расширяемых).

Z>Контринтуитивно

Z>
Z>macro TypeDeclaration;
Z>

Z>Как минимум abstract macro, а лучше что нибудь типа: extension point и sealed extension point.

Можно и abstract. Хотя это будет не более чем синтаксический мусор. Все равно макрос без тела не может описывать ничего кроме расширяемого "правила".

Сначала была идея задавать расширяемому макросу дефолтное тело, но по ходу конкретизации реализации стало ясно, что в этом нет смысла. Расширения проще и удобнее описывать отдельно.

На мой взгляд получается весьма просто и понятно.

Z>Понятно как расширяет аст макрос без тела, непонятно как это делать в теле.


Еще раз. У нас есть две сущности:
1. Расширяемые макросы — это, по сути, правило грамматики которое не имеет собственного описания и не может иметь тела. Это чисто абстрактная вещь. Она только лишь задает информацию о том, что есть такое правило и его можно расширять.

2. Расширяющие макросы — это почти обычные макросы. Они могут иметь или не иметь тела и обязаны содержать описание грамматики (правила). При обращении к расширяемому макросу/правилу (из своей грамматики) они должны задавать силу связывания. Если сила связывания не задается, то они по умолчанию считается равной нулю.

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

Так понятнее?

Z>Непонятно что такое @::, если функция, нужно это объяснить и приделать юзинг.


Функция. И там об этом отдельно сказано. Просто это может быть встроенная функция (для встоенных операторов дотнета оно так и будет).

Если встроенной функции нет, то ее нужно будет объявить явно. Естественно для них будут работать все соглашения (пространства имен и т.п.). Я же просто показывал пример.

Более того — это ведь не более чем паттерн. Просто я предлагаю этот паттерн принять за правило. Эдакий стандартный механизм. Если нам нужен новый оператор, то синтаксис для него мы вводим вот таким простым макросом. Макрос переписывает синтаксис в вызов оператора как функции. А уже дальше можно перегрузить такую функцию в нужном месте и получить поддержку этого оператора.

В случае с оператором :: и списком (где он обычно применяется в Н1) кроме объявления такого макроса мы так же реализуем оператор @:: в list[T]. Это позволит использовать этот оператор со списком. При этом оператор уже не будет вмонтирован в парсер и типизатор, а будет введен универсальным образом.

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

Z>про лишние кавычки в

Z>
Z>  $atts public $partial class $name $typeParams $parents $constraints { $members "}"
Z>

Z>уже писали, но видимо снова пропущены.

Я уже их убрал.

Z>Двоеточие для приоритетов — неконсистентный стиль. Лучше ключевое слово, в крайнем случае другой смайлик (например обычные скобки, syntax expr1(11) "::" expr2(10)). Хотя экономить символы тут глупо, таких макросов минимум.


Не очень понял что тут "неконсистентного". Да и очень понял, что это означает .

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

Z>Химия с созданием одноименных типов и вариантов внутри класса сложна для понимания и будет вызывать ступор.


Может быть. Но это уже детали реализации. Для работы с АСТ будет в основном использоваться квази-цитирование. Так что всей этой химии не будет видно.

Просто без деталей можно много на фантазировать. Мне важно было понять как это можно эффективно реализовать. Я не все по этому поводу описал. Но продумал довольно серьезно. Вот некоторыми деталями поделился (чтобы не забыть ).

Z> Один и тот же идентификатор в разных областях видимости указывает на очень разные сущности.


Почему на разные?

Z>Этот код вызывает разрыв шаблона

Z>
Z>macro PartialModifier : Ast[bool]
Z>


Z>Ast[bool] это что? Аст из любого типа? Что мешает сделать его просто bool?


У немерла 1.х есть один иделогический баг. В нем попросту теряется некоторая информация. Например, описывая параметр макроса как int мы теряем информацию о его местоположении и реальном АСТ. А зачастую это нужно. Можно конечно описать его как PExpr и выскребать информацию о значении литерала вручную (попутно нагородив кучу проверок). Но это уже слишком объемно и сложно. В АСТ Н1 вообще то и дело теряется куча информации. Н2 должен быть безупречен в этом плане.

По сему мы не можем позвлить людям терять информацию. Если кто-то хочет видеть в АСТ простые типы данных вроде булева типа, то он обязан работать с оберткой которая кроме нужного ему типа хранит еще и всю нужную ирформацию об АСТ с которого эта информация получен.

Тоже касается и типов параметров макросов.

Можно попробовать спрятать всю эту байду за некоторой магией. Например, позволить описывать типы параметров и возвращаемых значений любыми типами, но за кулисами оборачивать их в Ast[T]. Ну, а далее предложить некий, опять таки волшебный, механизм для извлечения нужной информации. Но это будет не так то просто объяснить людям.

В прочем это тоже дискуссионный вопрос.

Во то что не обсуждается, так это то что параметры и возвращаемые значения синтаксических макросов всегда должны быть унаследованы от типа AST. Но это все нужно иметь на "физическом уровне". А для пользователя это можно и прятать.

Вот только не ясно, есть ли в этом смысл?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [N2] Синтаксические макросы
От: Ziaw Россия  
Дата: 27.09.11 03:28
Оценка:
Здравствуйте, VladD2, Вы писали:

Z>>
macro Class is TypeDeclaration
почему не
macro Class : TypeDeclaration
второе сильно понятнее и следует семантике :. Расширяет это другие макросы или нет, компилятор может вычислить самостоятельно. Для самого макроса это может быть абсолютно не важно, он самодостаточен.


VD>Потому что ":" тоже используется для указания типа в случае наличия тела.


VD>Это конечно вопрос дискуссионный. Пока я вижу это так.


VD>Кроме того синтаксис взять из новой версии PegGrammar (которую Вольфхаунд уже пол года не может дописать). Там is используется для расширения других макросов (расширяемых).


Я так и не понял, почему нельзя использовать : во всех сценариях, независимо от наличия тела. Синтаксис PegGrammar конечно важен, но лучше подгонять его под язык, чем наоборот.

VD>Можно и abstract. Хотя это будет не более чем синтаксический мусор. Все равно макрос без тела не может описывать ничего кроме расширяемого "правила".


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

Z>>Понятно как расширяет аст макрос без тела, непонятно как это делать в теле.


VD>Еще раз. У нас есть две сущности:

VD>1. Расширяемые макросы — это, по сути, правило грамматики которое не имеет собственного описания и не может иметь тела. Это чисто абстрактная вещь. Она только лишь задает информацию о том, что есть такое правило и его можно расширять.

Я понял, вопрос не про них.

VD>2. Расширяющие макросы — это почти обычные макросы. Они могут иметь или не иметь тела и обязаны содержать описание грамматики (правила). При обращении к расширяемому макросу/правилу (из своей грамматики) они должны задавать силу связывания. Если сила связывания не задается, то они по умолчанию считается равной нулю.


Как раз про них. Как задать новый тип аст, если новый синтаксис не вводится?

VD>Если встроенной функции нет, то ее нужно будет объявить явно. Естественно для них будут работать все соглашения (пространства имен и т.п.). Я же просто показывал пример.


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

Z>>Двоеточие для приоритетов — неконсистентный стиль. Лучше ключевое слово, в крайнем случае другой смайлик (например обычные скобки, syntax expr1(11) "::" expr2(10)). Хотя экономить символы тут глупо, таких макросов минимум.


VD>Не очень понял что тут "неконсистентного". Да и очень понял, что это означает .


VD>Вполне стандартный стиль для Немерла задавать уточнения через двоеточие. Вот на счет явного задания силы связывания в виде цифр (кстати, это не приоритеты, хотя и близко к этому) я бы подискутировал. Лучше было бы ввести группы приоритетов и отталкиваться от них. Вот только опять таки это не приоритеты. Так что может выйти логический конфуз.


Уточнение типа. Приоритет ну никак не связывается у меня с типом.

Группы да, логичнее. Можно не обязательно группы, можно прямо на библиотечные/свои операторы ссылаться:

macro Cons is Expr
  syntax expr1 "::" expr2;
  expr1 priority is less than Add.expr1;   // думаю, достаточно просто следовать правилу, называть операнды exprN, всем должно быть понятно
  expr2 priority is less than Cons.expr1;
{
  <[ @::(expr1, expr2) ]>
}


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

Z>>Ast[bool] это что? Аст из любого типа? Что мешает сделать его просто bool?


VD>У немерла 1.х есть один иделогический баг. В нем попросту теряется некоторая информация. Например, описывая параметр макроса как int мы теряем информацию о его местоположении и реальном АСТ. А зачастую это нужно. Можно конечно описать его как PExpr и выскребать информацию о значении литерала вручную (попутно нагородив кучу проверок). Но это уже слишком объемно и сложно. В АСТ Н1 вообще то и дело теряется куча информации. Н2 должен быть безупречен в этом плане.


Понял.

VD>Можно попробовать спрятать всю эту байду за некоторой магией. Например, позволить описывать типы параметров и возвращаемых значений любыми типами, но за кулисами оборачивать их в Ast[T]. Ну, а далее предложить некий, опять таки волшебный, механизм для извлечения нужной информации. Но это будет не так то просто объяснить людям.


Да не, не надо магий. Просто я хотел узнать причину.
Re[3]: [N2] Синтаксические макросы
От: Ziaw Россия  
Дата: 27.09.11 03:33
Оценка:
Здравствуйте, VladD2, Вы писали:

Z>>про лишние кавычки в

Z>>
Z>>  $atts public $partial class $name $typeParams $parents $constraints { $members "}"
Z>>

Z>>уже писали, но видимо снова пропущены.

VD>Я уже их убрал.


В одном месте еще остались.
Re[4]: [N2] Синтаксические макросы
От: catbert  
Дата: 27.09.11 10:45
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>Я так и не понял, почему нельзя использовать : во всех сценариях, независимо от наличия тела. Синтаксис PegGrammar конечно важен, но лучше подгонять его под язык, чем наоборот.


Я так понял, : это просто возвращаемое значение. А расширяет именно is. То есть макрос MyMacro : Expr возвращает Expr, но при этом не является расширением Expr-а. Правда, не знаю зачем это
Re[4]: [N2] Синтаксические макросы
От: catbert  
Дата: 27.09.11 10:46
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

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


Z>
Z>macro Cons is Expr
Z>  syntax expr1 "::" expr2;
Z>  expr1 priority is less than Add.expr1;   // думаю, достаточно просто следовать правилу, называть операнды exprN, всем должно быть понятно
Z>  expr2 priority is less than Cons.expr1;
Z>{
Z>  <[ @::(expr1, expr2) ]>
Z>}
Z>


is less than? серьезно? столько слов для expr1 < expr2?
Re[5]: [N2] Синтаксические макросы
От: Ziaw Россия  
Дата: 27.09.11 13:40
Оценка:
Здравствуйте, catbert, Вы писали:

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


Z>>
Z>>macro Cons is Expr
Z>>  syntax expr1 "::" expr2;
Z>>  expr1 priority is less than Add.expr1;   // думаю, достаточно просто следовать правилу, называть операнды exprN, всем должно быть понятно
Z>>  expr2 priority is less than Cons.expr1;
Z>>{
Z>>  <[ @::(expr1, expr2) ]>
Z>>}
Z>>


C>is less than? серьезно? столько слов для expr1 < expr2?


Язык для создания DSL у нас почему-то регулярно скатывается к непонятным смайликам. expr1 < expr2 для меня совершенно однозначная конструкция никак не связанная с приоритетами, а expr1 priority < expr2 совсем плохо выглядит.
Re: [N2] Синтаксические макросы
От: Дьяченко Александр Россия  
Дата: 27.09.11 13:51
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Привел статью посвященную синтаксическим макросам Н2 в соответствие с текущим их пониманием.


Macros     = "macro" name (":" type / is type)? "syntax" syntax "{" expression "}";


is как и двоиточее должен быть в кавычках.
... << RSDN@Home 1.2.0 alpha 5 rev. 1536>>
Re: [N2] Синтаксические макросы
От: Дьяченко Александр Россия  
Дата: 27.09.11 14:20
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Привел статью посвященную синтаксическим макросам Н2 в соответствие с текущим их пониманием.


Ниже приведены примеры паттернов распознающих класс описанный макросом «Class». Распознают любой класс:

<[ TypeDeclaration.Class:
$atts $mods $partial class $name $typeParams $parents $constraints { $members }
]>
Распознает класс помеченный модификатором «public» (и не имеющий других модификаторов):

<[ Class:
$atts public $partial class $name $typeParams $parents $constraints { $members "}"
]>
Распознает

<[ Class:
abstract class MyClass : ..$parents { $members }
]>


  1. Про оставшиеся кавычки уже говорили.
  2. Почему в квазицитат-ах то "TypeDeclaration.Class:", то "Class:" используется? Я догадываюсь, но надо или пояснить, или сделать одинаковым.


macro TypeDeclaration;

Описанный выше макрос Class как раз и расширяет этот макрос. Кроме макроса Class, в базовом языке, описаны еще макросы Struct, Delegate, Enum, Variant и Type.


Для лучшего понимания примера идущего далее, я бы описал macro-class и как уже говорили abstract не помешает.

macro class CoreCyntax
{
    abstract macro TypeDeclaration;
    
    ...
}
... << RSDN@Home 1.2.0 alpha 5 rev. 1536>>
Re[4]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.09.11 16:41
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Я так и не понял, почему нельзя использовать : во всех сценариях, независимо от наличия тела. Синтаксис PegGrammar конечно важен,


Потому что есть три разных случая:
1. Объявление макроса с явным заданием типа возвращаемого значения.
2. Объявление макроса расширяющего другой макрос.
3. Объявление расширяемого макроса.

Можешь предложить свой синтаксис для этих трех случаев, а мы рассмотрим его. Я за синтаксис не держусь. Будет лучше моего, возьмем его.

Z>но лучше подгонять его под язык, чем наоборот.


У языка еще должен быть смысл, а не только синтаксис. Не можем же мы выразить разные смысловые случаи одним синтаксисом? Нет. Вот и нужно найти три синтаксических решения. То что я предложил, меня устраивает . Предлагай свой.

VD>>Можно и abstract. Хотя это будет не более чем синтаксический мусор. Все равно макрос без тела не может описывать ничего кроме расширяемого "правила".


Z>Не мусор, а токен дающий понимание человеку, не компилятору.


Отсутствие тела и так дает нужное понимание. А вот "abstract" может путать, так как человек может думать о таком макросе/правиле как о виртуальной функции. А это неверное восприятие.

Z>Как и абстрактный метод, который мог бы быть просто методом без тела, однако, читая в коде слово abstract, лучше понимаешь происходящее.


Ну, я в общем-то не против. По-моему это бессмысленно, но если кому-то так понятнее, то пусть будет так. Можно просто провести голосование, например.

VD>>Еще раз. У нас есть две сущности:

VD>>1. Расширяемые макросы — это, по сути, правило грамматики которое не имеет собственного описания и не может иметь тела. Это чисто абстрактная вещь. Она только лишь задает информацию о том, что есть такое правило и его можно расширять.

Z>Я понял, вопрос не про них.


Ну, так их нужно выражать как-то!

VD>>2. Расширяющие макросы — это почти обычные макросы. Они могут иметь или не иметь тела и обязаны содержать описание грамматики (правила). При обращении к расширяемому макросу/правилу (из своей грамматики) они должны задавать силу связывания. Если сила связывания не задается, то они по умолчанию считается равной нулю.


Z>Как раз про них. Как задать новый тип аст, если новый синтаксис не вводится?


Чё? Нет нового синтаксиса, нет и нового АСТ. Пользуйся старым.

VD>>Если встроенной функции нет, то ее нужно будет объявить явно. Естественно для них будут работать все соглашения (пространства имен и т.п.). Я же просто показывал пример.


Z>Угу, я и намекал, на то, что в примере этого нет. Надо бы его расширить кодом @::. Он довольно прост и придаст законченный вид описанию операторов.


Что расширить то? Приведи пример.

Z>Уточнение типа. Приоритет ну никак не связывается у меня с типом.


А причем тут тип? В квази-цитатх уточнения не только тип описывают. Опять же критикуешь — предлагай. Напиши свой пример, погляди сам на то что получилось, и покажи другим.

Z>Группы да, логичнее. Можно не обязательно группы, можно прямо на библиотечные/свои операторы ссылаться:


Нельзя — это тупиковый путь. У приоритетов есть именно группы. А операторов можно банально еще не быть. Они же могут разными (независимыми) библиотеками предоставляться. Целые этому не мешают. Надо только давать "дыры" между силами связывания (как это делается сейчас). Группы тоже, скорее всего, прокатят. А вот прямые ссылки не прокатят. Я уже об этом думал.

Группы можно задать отдельно. Это будет очень хорошо читаться. Вот пример групп для C#-а:

Primary
Unary
Multiplicative
Additive
Shift
Relational and type testing
Equality
Logical AND
Logical XOR
Logical OR
Conditional AND
Conditional OR
Null coalescing
Conditional
Assignment and lambda expression

Не трудно описать эти группы в декларативной манере. Например, так:
binding power Primary              >   Unary;
binding power Unary                >   Multiplicative;
binding power Multiplicative       >   Additive;
binding power Additive             >   Shift;
binding power Shift                >   Relational;
binding power Relational           ==  TypeTesting;
binding power TypeTesting          >   Equality;
binding power Equality             >   LogicalAnd;
binding power LogicalAnd           >   LogicalXor;
binding power LogicalXor           >   LogicalOr;
binding power LogicalOr            >   ConditionalAnd;
binding power ConditionalAnd       >   ConditionalOr;
binding power ConditionalOr        >   NullCoalescing;
binding power NullCoalescing       >   Conditional1;
binding power Conditional1         >   Conditional2;  // нужно две группы так как ?: правоассоциативен
binding power Conditional2         >   Assignment1;
binding power Assignment1          >=  Assignment2;   // нужно две группы так как = правоассоциативен
binding power Assignment2          ==  Lambda;
binding power Lambda;

Теперь описание операторов C# будет выглядеть так:
// левоассоциативные операторы
macro @&& is Expr // можно использовать имя в виде оператора перед которым идет @
  syntax expr1 : ConditionalAnd "&&" expr2 : ConditionalAnd;
{
  @&&(expr1, expr2)
}

macro @|| is Expr
  syntax expr1 : ConditionalOr "||" expr2 : ConditionalOr;
{
  @||(expr1, expr2)
}

// правоассоциативный оператор!
macro Conditional is Expr // ... а моно и в виде идентификатора.
  syntax condition : Assignment1 "?" trueExpr : Assignment2 ":" falseExpr; // сила связывания для falseExpr == 0
{
  op_Conditional(condition, trueExpr, falseExpr)
}



Z>
Z>macro Cons is Expr
Z>  syntax expr1 "::" expr2;
Z>  expr1 priority is less than Add.expr1; 
Z>  expr2 priority is less than Cons.expr1;
Z>{
Z>  <[ @::(expr1, expr2) ]>
Z>}
Z>


Какое-то литературное произведение получилось.

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

Грамматика станет немного чище, но объем текста во всем макросе только увеличится.

macro Cons is Expr
  syntax expr1 "::" expr2;
  binding power: expr1 = Cons1, expr2 = Cons2
{
  <[ @::(expr1, expr2) ]>
}

или
macro Cons is Expr
  syntax expr1 "::" expr2;
  binding power: expr1 = 21, expr2 = 20
{
  <[ @::(expr1, expr2) ]>
}


Можно конечно и так. Тут можно просто устроить голосование. Кому какой вариант больше нравится.

Z>Плюс в том, что синтаксис будет избавлен от мух приоритетов. Но компилятору придется решить простенькую логическую задачку перед компиляцией, либо доказать ее невозможность. Чую — от пролога в виде DSL не отвертеться


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

Технических проблем тут нет.

Вопрос только в синтаксическом решении.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [N2] Синтаксические макросы
От: Ziaw Россия  
Дата: 27.09.11 18:26
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Потому что есть три разных случая:

VD>1. Объявление макроса с явным заданием типа возвращаемого значения.


macro f(a : Expr, b : Expr) : Expr
{
  <[ $a + $b ]>
}


VD>2. Объявление макроса расширяющего другой макрос.


Расширяют не макрос, а синтаксис, список выбора для парсера, где может ожидаться некий тип AST.

macro f : Expr
syntax "f" "(" $a "," $b ")";
where a : Expr, b : Expr;
{
  <[ $a + $b ]>
}



VD>3. Объявление расширяемого макроса.


А нужно ли оно вообще? Если нам нужен TopDeclaration, мы берем все макры с синтаксисом которые возвращают TopDeclaration. Я не могу придумать ситуации, кода нам требуется абстрактный макрос, типа определяем синтаксис, но оставляем на откуп другим сборкам внутренние детали? Ну так надо объяви

VD>>>Еще раз. У нас есть две сущности:

VD>>>1. Расширяемые макросы — это, по сути, правило грамматики которое не имеет собственного описания и не может иметь тела. Это чисто абстрактная вещь. Она только лишь задает информацию о том, что есть такое правило и его можно расширять.

А зачем эта информация нужна? Если правило где-то используется — оно уже известно, если не используется — нафик оно?

Z>>Угу, я и намекал, на то, что в примере этого нет. Надо бы его расширить кодом @::. Он довольно прост и придаст законченный вид описанию операторов.


VD>Что расширить то? Приведи пример.


Расширить пример описания операторов примером функции @::. Чтобы понятно было, что это вообще и как их создавать.

Z>>Группы да, логичнее. Можно не обязательно группы, можно прямо на библиотечные/свои операторы ссылаться:


VD>Нельзя — это тупиковый путь. У приоритетов есть именно группы. А операторов можно банально еще не быть. Они же могут разными (независимыми) библиотеками предоставляться. Целые этому не мешают. Надо только давать "дыры" между силами связывания (как это делается сейчас). Группы тоже, скорее всего, прокатят. А вот прямые ссылки не прокатят. Я уже об этом думал.


Почему не прокатят?

VD>Задавать силу связывания относительно других операторов — это плохая идея. Да и столько букв — это тоже лишнее.


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

VD>Грамматика станет немного чище, но объем текста во всем макросе только увеличится.


Z>>Плюс в том, что синтаксис будет избавлен от мух приоритетов. Но компилятору придется решить простенькую логическую задачку перед компиляцией, либо доказать ее невозможность. Чую — от пролога в виде DSL не отвертеться


VD>Какой на фиг пролог? Нет тут никаких задач.


Чтобы получить числовые приоритеты из кучи условий требуется решить логическое уравнение.
Re[2]: [N2] Синтаксические макросы
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.09.11 18:42
Оценка:
Здравствуйте, Дьяченко Александр, Вы писали:

ДА>*Про оставшиеся кавычки уже говорили.

ДА>*Почему в квазицитат-ах то "TypeDeclaration.Class:", то "Class:" используется? Я догадываюсь, но надо или пояснить, или сделать одинаковым.

Исправил.


ДА>Для лучшего понимания примера идущего далее, я бы описал macro-class и как уже говорили abstract не помешает.


"abstract" добавил, уломали .

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

Так же дописал "Левая рекурсия".
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: [N2] Синтаксические макросы
От: WolfHound  
Дата: 27.09.11 19:53
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>Чтобы получить числовые приоритеты из кучи условий требуется решить логическое уравнение.

Нет. Требуется произвести топологическую сортировку.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.