Каковы границы расширения синтаксиса в Н1
От: m.e.  
Дата: 20.03.12 20:13
Оценка:
VD>От части прав и Матумба. Синтаксическое расширение Н1 далеко от идеала. Например, для поддержки линковского синтаксиса пришлось заворачивать его в строку:
VD>linq <# from x in xs select x * x #>


вот, кстати, хотел задать вопрос — каковы границы расширения синтаксиса в Н1 (т.е. что можно, а что уже нельзя)? этот вопрос стоит задать в отдельном треде, или ты прямо тут расскажешь это, и покажешь, почему пришлось синтаксис вынести в строку?

понятно, что "расширение синтаксиса, завернутое в строку" позволяет сделать все что угодно — так что имеются в виду граници расширения синтаксиса другими способами

21.03.12 00:38: Ветка выделена из темы How to popularize Nemerle
Автор: VladD2
Дата: 18.03.12
— VladD2
Re: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.12 22:08
Оценка:
Здравствуйте, m.e., Вы писали:

ME>вот, кстати, хотел задать вопрос — каковы границы расширения синтаксиса в Н1 (т.е. что можно, а что уже нельзя)?


1. Н1 использует лексер, препроцессор и препарсер. Изменить их из макросов нельзя.
Лексер определяет то как Н1 разбирает лексемы (режет текст на токены). Например, последовтаельность символов "+=+" буде распознана как один оператор (например, в C# она может быть распознана как операторы "+=" и "+".
Препроцессор аналогичен оном в C# и никак не изменяем.
Препарсер отвечает за:
* Подгрузку и выгрузку синтаксических расширения.
* Свертку токенов по группам (на основе скобок).
* Абстрагирование от типа синтаксиса (скобочного или на базе отступов).

Все эти решения являются компромисными и в той или иной степени снижают расширяемость.
Так при свертке по скобкам производится обработка знаков разделителей (запятых, точек с запятых и т.п.). Это приводт к тому, что казалось бы простой синтаксис вроде:
select a, b

не может быть разобран.

Для сравнения в Н2 используется безлексерный генерируемый расширяемый парсер который не имеет подобных проблем.

2. Макросы Н1 позволяют расширять только предопределенные создателями места в грамматике: набор выражений, заголовок типа (новый тип определить нельзя), член типа, заголовок метода или эксессора свойства/события, параметр.

3. Макросы могут быть лексическими (так называемые raw-макросы) и синтаксическими. Первые позволяют разбирать более сложные грамматики (любые удовлетворяющие правилам лексера и препарсера). Вторые позволяют разбирать набор ключевых слов, скобок и выражений.

Здесь надо обратить особое внимание на слово "выражение". Заметьте, не произвольная грамматика, а только выражение.

Например, нельзя определить макрос:
macro ForEach(pattern, collectoin, body)
  syntax ("foreach", "(", pattern, "in", collectoin, ")", body)
{
  ...
}

так как в первый это выражение, а в немерле есть бинарный оператор "in".
Если определить описанный выше синтаксис, то при разборе будет всегда выдаваться сообщение об ошибке, так как в параметр pattern будет помещаться выражение in, а далее парсер не сможет найти ключевое слово in.
Это вынуждает прибегать к хитрости. У реального макроса ForEach есть только два параметра:
  macro @foreach (inexpr, body)
  syntax ("foreach", "(", inexpr, ")", body)
  {

а выражения pattern и collectoin добываются позже с помощью паттерн-матчинга.
Причем этот трюк работает не всегда, так как не всегда грамматика оператора совпадает с требуемой грамматикой.

О гибкости конструкций верхнего уровня уже и речи быть не может.

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

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

Фактически изменение синтаксиса любого языка созданного на базе Н2 (подчеркиваю, не только Н2 как языка, но и, например, C#) ограничено только согласованностью грамматики языка и соответствию правилам контекстно-свободной грамматики (точнее правилам нашего генератора парсеров, так как они несколько отличаются от КСГ).

Точкой расширения в грамматиках Н2 задаются авторами этих грамматик. Макрос сможет создавать новые точки расширения. Для этого достаточно просто объявить правило без тела.

4. В Н1 макросы типизируются после раскрытия (точнее макросы раскрываются в процессе типизации). Макрос по сути нетипизирован. Чтобы получить выгоду от знания и управления типами он должен вмешаться в процесс типизации и произвести ручную типизацию подвыражений (или сгенерированного кода). Это не позволяет перегружать синтаксические расширения. Например, не может быть два foreach-а с одинаковым синтаксисом, но разными реализациями (в зависимости от типов аргументов). Это вынуждает разработчика макроса реализовывать всю логику внутри одного макроса (используя ручную типизацию). А это уменьшает возможности расширения, так как нельзя создать альтернативую реализацию макроса (точнее такую реализацию нельзя будет использовать параллельно с основной в одной области видимости).

ME>этот вопрос стоит задать в отдельном треде, или ты прямо тут расскажешь это, и покажешь, почему пришлось синтаксис вынести в строку?


Вынес в отдельную тему.

ME>понятно, что "расширение синтаксиса, завернутое в строку" позволяет сделать все что угодно — так что имеются в виду граници расширения синтаксиса другими способами


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

Именно это позволит нам реализовать не один язык, а любое их кличество.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Каковы границы расширения синтаксиса в Н1
От: m.e.  
Дата: 21.03.12 14:28
Оценка:
ну что, содержательно

вечером напишу несколько ответов
Re[2]: Каковы границы расширения синтаксиса в Н1
От: m.e.  
Дата: 21.03.12 19:40
Оценка:
во-первых, если у вас еще такой терминологии нет, надо ввести понятия прикладного программиста (который использует DSL) и системного (который DSL создает)

теперь уже можно обсудить оператор +=+

и тут надо задать вопрос — Н2 будет Compiler Construction Kit или же контейнером для Embedded DSL?

если ССК, то да, правильно, должна быть возможность определить оператор +=+, а вот если контейнер, то, по крайней мере с точки прикладного программиста, возможность системному программисту задать оператор +=+ выглядит как-то страшно

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

вообще какой-то порядок хочется иметь, что-то хочется запретить, и разбор по произвольному PEG меня несколько страшит
Re[2]: Каковы границы расширения синтаксиса в Н1
От: m.e.  
Дата: 21.03.12 19:51
Оценка:
VD>Препарсер отвечает за:
VD>* Подгрузку и выгрузку синтаксических расширения.
VD>* Свертку токенов по группам (на основе скобок).
VD>* Абстрагирование от типа синтаксиса (скобочного или на базе отступов).

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

VD>Все эти решения являются компромисными и в той или иной степени снижают расширяемость.

VD>Так при свертке по скобкам производится обработка знаков разделителей (запятых, точек с запятых и т.п.). Это приводт к тому, что казалось бы простой синтаксис вроде:
VD>select a, b

VD>не может быть разобран.

это "select" CommaSeparatedList

препрарсер не может быть усовершенствован, чтобы выдавать CommaSeparatedList?

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


VD>Если определить описанный выше синтаксис, то при разборе будет всегда выдаваться сообщение об ошибке, так как в параметр pattern будет помещаться выражение in, а далее парсер не сможет найти ключевое слово in.

VD>Это вынуждает прибегать к хитрости. У реального макроса ForEach есть только два параметра:
VD>а выражения pattern и collectoin добываются позже с помощью паттерн-матчинга.
VD>Причем этот трюк работает не всегда, так как не всегда грамматика оператора совпадает с требуемой грамматикой.

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

вот что неудобно — это получается "двухступенчатость" разбора, но для нее можно сделать свои хелперы
Re[2]: Каковы границы расширения синтаксиса в Н1
От: m.e.  
Дата: 21.03.12 19:53
Оценка:
а теперь частный вопрос — можно ли объявления переменных в Н1 задавать по-другому?

скажем, var x = Type: value

или же синтаксис объявления переменных жестко прошит?
Re[3]: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.12 21:18
Оценка:
Здравствуйте, m.e., Вы писали:

ME>во-первых, если у вас еще такой терминологии нет, надо ввести понятия прикладного программиста (который использует DSL) и системного (который DSL создает)


Понятие "прикладной программист" есть. Системного — нет. Это просто "автор макроса" или "создатель макроса". "Системный", на мой взгляд, тут не к месту.

ME>Н2 будет Compiler Construction Kit или же контейнером для Embedded DSL?


Во-первых, не "Compiler", а "language". Создание компилятора — это только одна из задач. Мы хотим обеспечить средства для создания всего спектра средств необходимых сегодня для языка. Это и компилятор, и интеграция с IDE, и средств рефакторинга (в том числе механизмы создания пользовательских рефакторингов), и многое другое.

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

На самом деле слово "фрэймворк" я использую для того чтобы непосвященным было проще думать об этом используя более-менее привычный термин. По жизни же это будет решение на основе немерла (по началу первого) которое будет позволять создавать синтаксические/семантические расширения и трансляцию их в более низкоуровневый язык. Просто расширять можно будет все что угодно. В корне иерархии расширения будет стоять файл. Можно будет описать некоторое расширение файла и создать для него поддержку с нуля. Это тоже будет расширением синтаксиса.

Таким образом мы практически не будем разделять понятия внешнего и внутреннего ДСЛ-ей. Внешний ДСЛ — это синтаксическое расширение на уровне файла.

Более того, во внешних ДСЛ-ях можно будет использовать другие языки или их подмножества. Например, на базе Н2 можно будет реализовать поддержку разных ASP или Razor-ов. Например, .cshtml-файлы содержат рекурсивно-вложенные конструкции ХТМЛ-я и C#.

ME>если ССК, то да, правильно, должна быть возможность определить оператор +=+, а вот если контейнер, то, по крайней мере с точки прикладного программиста, возможность системному программисту задать оператор +=+ выглядит как-то страшно


Ничего страшного тут нет. В Н1 можно определять новы операторы просто объявляя их в классах. Никаких проблем это не вызывает.

Н2 как фрэймворк будет позволять определять как языки с заранее заданным набором операторов, так и языки с расширяемым набором операторов.


ME>я бы решал эту задачу проще — на уровне лексера,


В Н2 физически не будет лексеров.

Каждое синтаксическое расширение будет обладать своими микро-лексерами объявляемыми прямо в рамках.

ME>или если лексера у вас нет — значит где-то-там, где можно забанить разбор, выдающий лексемы, скажем, состоящие из не-альфанум и содержащие "=" не на последней позиции


Будет понятие "терминальное правило". Вот в нем ты и описываешь лексему. И это может быть как "литерал" типа "+=+", так и рекурсивная грамматика типа ('+' | '=' | '-')+. Всего и делов.

ME>вообще какой-то порядок хочется иметь, что-то хочется запретить, и разбор по произвольному PEG меня несколько страшит


Запрещать или разрешать — это прераготива того кто описывает язык. Мы же предоставляем средство. Скажем если ты решишь воспроизвести на Н2 С++, то можешь захардкодить список операторов и все. Если ты воспроизводишь немерл, то сделай его автоматически-расширяемым. Ну, а в других случаях можно разрешать явно описываемые операторы.

В общем — есть выбор.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.12 21:44
Оценка:
Здравствуйте, m.e., Вы писали:

ME>а теперь частный вопрос — можно ли объявления переменных в Н1 задавать по-другому?

ME>скажем, var x = Type: value

Можно сделать макрос который объявит переменную. Народ воспроизводит синтаксис C# (с var).

ME>или же синтаксис объявления переменных жестко прошит?


Зашитость не мешает ввести новую конструкцию которая перепишет код в старую.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.03.12 22:08
Оценка:
Здравствуйте, m.e., Вы писали:

VD>>Препарсер отвечает за:

VD>>* Подгрузку и выгрузку синтаксических расширения.
VD>>* Свертку токенов по группам (на основе скобок).
VD>>* Абстрагирование от типа синтаксиса (скобочного или на базе отступов).

ME>и это выглядит разумно, и мне лично нравится гораздо больше произвольного PEG-а (хотя, может, он там не произвольный вовсе?)


Оно выглядит разумно пока не столкнулся с ограничениями имеющимися на практике.

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

ME>
VD>>select a, b
ME>

VD>>не может быть разобран.

ME>это "select" CommaSeparatedList


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

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

ME>препрарсер не может быть усовершенствован, чтобы выдавать CommaSeparatedList?


Придется пол парсера переписать. Учитывая, что есть более совершенное решение — это пустое занятие.

ME>да, я понимаю, скорее всего придется приоритеты иметь общие для разных синтаксических конструкций, но ведь это благо для прикладного программиста — меньше запоминать надо!


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

Бояться за прикладного программиста не стоит. Он использует конечный язык. Его все равно придется учить. Мы же предоставим автоматически формируемую документацию. Так что изучать расширения будет просто.

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

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

Для каждого языка реализованного средствами Н2 (будь то мелкий ДСЛ или полноценный ЯП) мы сможет сгенерировать неплохую интеративную документацию. И все это практически бесплатно.

VD>>Если определить описанный выше синтаксис, то при разборе будет всегда выдаваться сообщение об ошибке, так как в параметр pattern будет помещаться выражение in, а далее парсер не сможет найти ключевое слово in.

VD>>Это вынуждает прибегать к хитрости. У реального макроса ForEach есть только два параметра:
VD>>а выражения pattern и collectoin добываются позже с помощью паттерн-матчинга.
VD>>Причем этот трюк работает не всегда, так как не всегда грамматика оператора совпадает с требуемой грамматикой.

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


Ты явно не понимаешь о чем говоришь. Операторы — это отдельное правило грамматики. Оператор расширяет это правило добавляя альтернативу. Любым оператор быть не может по определению.

В Н2 можно будет просто задать произвольную грамматику. Уже ее автор будет решать нужно ли ему использовать операторы или лучше описать отдельную грамматику.

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

ME>вот что неудобно — это получается "двухступенчатость" разбора, но для нее можно сделать свои хелперы


Ты что-то там гадаешь. Мне то не интересно. Я тебе описываю результаты анализа практического опыта использования.

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

В общем, у нас есть то что нужно для бескомпромиссность реализации. Тут просто нечего обсуждать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Каковы границы расширения синтаксиса в Н1
От: _Claus_  
Дата: 22.03.12 12:30
Оценка:
VD>В общем, у нас есть то что нужно для бескомпромиссность реализации. Тут просто нечего обсуждать.

давай тогда втупую заменим парсер в N1 и сделаем жизнь лучше уже сейчас!
Re[5]: Каковы границы расширения синтаксиса в Н1
От: Аноним  
Дата: 22.03.12 12:33
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>давай тогда втупую заменим парсер в N1 и сделаем жизнь лучше уже сейчас!


Смотрел код Н1, проще сделать Н2.
Re[6]: Каковы границы расширения синтаксиса в Н1
От: _Claus_  
Дата: 22.03.12 13:57
Оценка:
А>Смотрел код Н1, проще сделать Н2.

Все может быть, только пять лет ждать мало кто согласится.
Re[7]: Каковы границы расширения синтаксиса в Н1
От: Аноним  
Дата: 22.03.12 14:11
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Все может быть, только пять лет ждать мало кто согласится.


Я думаЮ что частичная компиляция будет через годик. Полная лет через 5
Re[5]: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.12 21:32
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>давай тогда втупую заменим парсер в N1 и сделаем жизнь лучше уже сейчас!


Я думал об этом. Но кроме замены парсера еще придется переписать много чего. Всю инфраструктуру работу с макросами, например.

Работы получается довольно много.

Плюс пока не доделаны некоторые вещи по генератору парсеров полноценного решения все равно не получить.

Если хочешь можешь взяться за это дело когда генератор парсеров будет доведен до нуля. Я могу помогать консультациями.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Каковы границы расширения синтаксиса в Н1
От: _Claus_  
Дата: 22.03.12 21:45
Оценка:
VD>Если хочешь можешь взяться за это дело когда генератор парсеров будет доведен до нуля. Я могу помогать консультациями.

Я могу взяться за текущий парсер. через месяц-два. че то мне кажется, что можно его допилить до правильного состояния.
чтобы он бесскобочные выражения мог разбирать и linq подобные.
логика его в основном мне понятна. и как расширить ее — введением различения выражения и блока выражений, должно вписаться.
Re[7]: Каковы границы расширения синтаксиса в Н1
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.03.12 22:15
Оценка:
Здравствуйте, _Claus_, Вы писали:

_C_>Я могу взяться за текущий парсер. через месяц-два. че то мне кажется, что можно его допилить до правильного состояния.


Там проблемы в дизайне. Без серьезной переделки там ничего не сделать.

_C_>чтобы он бесскобочные выражения мог разбирать и linq подобные.

_C_>логика его в основном мне понятна. и как расширить ее — введением различения выражения и блока выражений, должно вписаться.

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