Re[28]: Опциональные типы
От: WolfHound  
Дата: 13.03.17 10:50
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Так и что я "несу"-то?

V>>>Покажешь хоть раз или нет?
WH>>Да уже много раз показывал.
V>Т.е. не можешь.
Одних ЗТ в С++ более чем достаточно.

V>NetBeans IDE изначально точно такой же учебный студенческий проект, как и ANTLR.

Тем не менее ANTLR для IDE использовать пытаются.

V>ASN.1 смотрел?

V>А какие профили кодирования смотрел?
Ты собрался ASN.1 парсить при помощи ANTLR?
И после этого ты тут про адекватность говоришь?

WH>>Графическое представление грамматики тупо не нужно.

V>Наоборот. Единственная польза от подобных тулзов — это графическое представление грамматики и соответствующего AST.
Так в чём польза то?
Вот смотрим на твой первый скриншот.
Там есть визуализация iteration_statement.
И ровно то же самое написано в коде.
Ну и смысл?

WH>>Там по сравнению с текстом нет никакой новой информации.

V>Так у тебя дамп AST в виде текста? Или никакого дампа?
У меня есть дерево с двусторонней навигацией между АСТ и текстом из которого этот АСТ получен.

V>Ну и по самой грамматике — ес-но новой информации нет.

V>Есть другое представление имеющейся.
Зачем?
Что тебе даст стрелка, идущая мимо expression по сравнению со знаком "?" стоящим после expression?

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

Не похоже.

V>>>А профайлер грамматики у тебя есть?

V>>>Каким-либо образом можно узнать в Нитре, на сколько операций парсинга стало больше-меньше на тестовом примере после изменения грамматики?
WH>>Никто не просил. Вот и не сделали за ненадобностью.
V>Ясно.
V>Узок их круг, страшно далеко они от народа. (С) Герцен.
Парсер нитры очень предсказуем в отличии от всяких ANTLR'ов у которых производительность от каждого чиха скачет.

V>Дело в самом "ядре", сверху которого накручиваются потом примочки, верно?

V>Потому что чем дальше, тем меньше путей к отступлению.
V>Не переиграешь потом ничего в ядре, инерционность будет большая.
Ядро уже не один раз переделывалось без изменения синтаксиса. И всё продолжало работать.

V>>>Там вообще своё восстановление написать можно, бо кишки Бизона открыты.

WH>>Ты вообще понимаешь какой неадекват ты тут несёшь?
V>Да ну? Это я, значит, по обрывкам информации ориентируюсь и считаю, что владею ею? ))
1)Именно ты.
2)Как эти две твои фразы соотносятся между собой не ясно.


WH>>>>>>Это пользователь должен описывать правила восстановления руками. Ахринеть.

WH>>>>>>1)Это куча мутной работы.
V>>>>>Это примерно такая же работа, как в языке расширенных регулярных выражений отличать конечные правила от промежуточных.
WH>>>>Что за бред опять?
V>>>Что именно ты тут опять не понял?
WH>>Я понял, что ты не в состоянии держать контекст разговора.
V>Контекст тут один — формальные грамматики.
После этого про адекватность больше не говори.

WH>>Я вернул то что ты потёр. А теперь попробуй объяснить, как одно связано с другим?

V>Ты мне можешь один раз прямо ответить на прямой вопрос — ты в ВУЗ-е учился на программиста или нет?
Успокойся. Про регулярные выражения я знаю намного больше чем ты.

V>В результирующем ДКА пометка конечного состояния (выхода) должна стоять только у целевых лексем, ес-но.

V>Т.е. в исходном описании грамматики необходимо как-то особо помечать целевые правила.
1)В нитре всё прекрасно работает без всяких пометок
    regex EscChar                   = '\\' | '/' | 'b' | 'f' | 'n' | 'r'| 't' | 'u' HexDigit HexDigit HexDigit HexDigit
    {
      regex HexDigit                  = ['0'..'9', 'a'..'f', 'A'..'F'];
    }

      regex Quote   = '\"';
      regex Esc     = '\\' (Quote | EscChar);
      regex Escs    = Esc+;
      regex NotEscs = Any+ - (Any* (Quote | '\\' | NewLine) Any*);

Обрати внимание на NotEscs. Там из множества непустых строк вычитаются все строки, которые содержат Quote | '\\' | NewLine.
Вот такое вот вычитание одного бесконечного множества из другого.
И это просто частный случай более общей операции.
    public Xor(fsm1 : FSM, fsm2 : FSM) : FSM
    {
      Product([fsm1, fsm2], fun(([ok1, ok2])) { set => set.Contains(ok1) ^ set.Contains(ok2) })
    }

    public Sub(fsm1 : FSM, fsm2 : FSM) : FSM
    {
      Product([fsm1, fsm2], fun(([ok, fail])) { set => set.Contains(ok) && !set.Contains(fail) })
    }

    public Product(fsms : list[FSM], makeIsOkState : list[int] -> (Set[int] -> bool)) : FSM
    {
      def (result, resultStart) = FSM().NewStartState();
      def (result, resultOkStates) = fsms.Fold((result, []), (fsm, (result, resultOkStates)) =>
      {
        def (result, fsmStart, fsmOkStates) = result.IncludeFSM(fsm);
        def (result, fsmOkState) = result.NewState();
        def result = result.AddTransition(Transition.Epsilon(resultStart, fsmStart));
        def result = fsmOkStates.Fold(result, (okState, result) => result.AddTransition(Transition.Epsilon(okState, fsmOkState)));
        (result, fsmOkState :: resultOkStates);
      });
      MakeDeterministic(result, makeIsOkState(resultOkStates.Reverse()))
    }


2)Как это связано с ручным описанием восстановления не ясно.

V>В общем, для адекватного обсуждения требовалось желание собеседников "втыкать" в тему.

Мы предварительно посмотрели тесты производительности. И там всё было очень печально.

WH>>Хотя на практике скорость работы GLR это 80 мегабайт в час.

V>Это бред бредовый.
V>Разбор естественных языков, да еще по таблицам синонимов.
V>Если ты принимаешь технические решения под влиянием столь чудовищной ангажированности — то ты их не принимаешь вовсе. Ты тыкаешь пальцем в небо.
Да все тесты ГЛР имеют похожие цифры.

WH>>И если на основной парсер внимательно посмотреть, то он фактически ослабленный Эрли. И за счёт этого ослабления работает намного быстрее.

V>Если ты про Пакрат и у вас сохранён именно алгоритм Пакрата — то не совсем.
Естественно не совсем. Я же сказал ослабленный.

V>Пакрат запоминает удачные ветки разбора, Эрли все. Это принципиально. Держим это в уме и пытаемся ставить задачу.

Классический пакрат для каждой позиции в тексте запоминает результат разбора всех правил грамматики для этой позиции.
Естественно такую дурь на практике никто не реализует. Он так был сформулирован только для доказательства линейности.
Но это просто очередная демонстрация понимания тобой предмета.

V>А у тебя что? У тебя ровно наоборот — взят неадекватный алгоритм для невалидного исходника и шустрый для валидного.

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

V>Но этого мало — по твоим словам выходит так, что в случае ошибки парсинг запускается повторно. И это основной сценарий в процессе той самой активной набивки текста???

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

V>У меня основная претензия к Эрли — что кол-во занимаемой памяти/степень параллельности начинает расти с ростом длины цепочки.

Ты бредишь.
Память эрли кушает там, где есть куча неоднозначностей.
Но GLR будет делать то же самое.
А там, где неоднозначностей нет там всё линейно.
Особенно это касается моего варианта Эрли у которого в правой части правил не последовательность, а произвольный автомат. Ибо вместо бестолковой рекурсии он просто бежит по автомату.
Ну и не использую я Эрли там, где всё однозначно. Он сразу на пакрат переходит.

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

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

V>Даже в том обсуждении про БНФ ты не понял очевидной вещи — это возможности автоматической трансформации грамматик.

Не нужно. Просто не нужно если алгоритм и так работает.

V>А людям для обработки нужно AST, которое удобное для банального понимания.

V>Но часто приходится подвергать грамматику факторизации/коррекции и получается уход от первоначальной идеи.
V>С AST по изменённой грамматике бывает работать неудобно.
А в случае с нитрой не приходится.
Прикинь.
Ты описываешь грамматику так как удобно, и она просто работает.

V>Кароч, в этом обсуждении могу похвалить — ты понял ОЧЕНЬ много.

Я тут ничего кроме банальностей, которые давно знал не сказал.
А вот ты так до сих пор ничего и не понял.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[29]: Опциональные типы
От: vdimas Россия  
Дата: 14.03.17 10:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>>>Да уже много раз показывал.

V>>Т.е. не можешь.
WH>Одних ЗТ в С++ более чем достаточно.

Ты эпично слился с ЗТ в С++. Если оттрекать весь спор с самого начала — ни одно моё утверждение не было ошибочным.
Ты мне приписывал всякую херню и "разбивал" её.
И тем более забавно, что ты сам дважды крупно крупно ошибся.
Чего и следовало ожидать, собсно.


V>>NetBeans IDE изначально точно такой же учебный студенческий проект, как и ANTLR.

WH>Тем не менее ANTLR для IDE использовать пытаются.

Пусть.
На каждую существующую платформу имеется 2-3 популярных ИДЕ, что оправдывает уникальность каждой такой разработки.
Ваша Нитра идёт на одну всего платформу, т.е. её потенциальный рынок тоже 2-3 построенных на ней ИДЕ.


V>>ASN.1 смотрел?

V>>А какие профили кодирования смотрел?
WH>Ты собрался ASN.1 парсить при помощи ANTLR?

Любой тулкит ASN.1 — это генератор парсеров.
Продвинутые такие тулкиты тоже имеют режим визуализации как грамматики, так и распаршенных данных.


WH>И после этого ты тут про адекватность говоришь?


Я про неадекватность:

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

С тобой явно что-то не то происходит.


WH>>>Графическое представление грамматики тупо не нужно.

V>>Наоборот. Единственная польза от подобных тулзов — это графическое представление грамматики и соответствующего AST.
WH>Так в чём польза то?

Дурацкий вопрос.
Ты пробовал читать схемы электрические принципиальные через net-list?
А карту местности через список координат населённых пунктов?
Ну вот попробуй.


WH>Вот смотрим на твой первый скриншот.

WH>Там есть визуализация iteration_statement.
WH>И ровно то же самое написано в коде.
WH>Ну и смысл?

Смысл появляется начиная от грамматики банального калькулятора, где через грамматику описывается приоритет операций.
И не надо мне опять про набивший оскомину ПЕГ, где приоритет задаётся явно через "правильную" очередность описания правил.
Мне надо без всякой "правильной" очередности.
Мне надо честный choice.


WH>>>Там по сравнению с текстом нет никакой новой информации.

V>>Так у тебя дамп AST в виде текста? Или никакого дампа?
WH>У меня есть дерево с двусторонней навигацией между АСТ и текстом из которого этот АСТ получен.

Дерево — это и есть графическое представление графа (масло масляное, но ничего не поделать).
А чего тогда спрашиваешь "зачем"?


V>>Ну и по самой грамматике — ес-но новой информации нет.

V>>Есть другое представление имеющейся.
WH>Зачем?
WH>Что тебе даст стрелка, идущая мимо expression по сравнению со знаком "?" стоящим после expression?

Покажет, правильно ли я поставил закрывающие скобки.


WH>Парсер нитры очень предсказуем в отличии от всяких ANTLR'ов у которых производительность от каждого чиха скачет.


Да, производительность top-down парсеров сильно зависит от вида грамматики.
Даже если речь об эквивалентных грамматиках.
Разве это новость? Это азы.

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

У меня на 3-м курсе был курсовик — построение лексического анализатора из текстового описания в форме расширенного языка описания регулярных грамматик.
Сам язык описания можно распарсить КС-парсером. Я писал тот самый ручной рекурсивный спуск с предпросмотром на 1-2 лексемы.
Т.е. да, рекурсивный спуск можно написать при минимуме теоретической подготовки для несложной КС-грамматики.

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

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

Я прекрасно помню, что примерно до 2008-го года "вы" были тут в резком меньшинстве. Это с вами, как раз-таки, был мало кто согласен. И ничего с тех пор НЕ изменилось — вас НЕ стало больше. Это случилось обратное — в период где-то 2007-2010-х гг стала происходить тотальная зачистка форума от "несогласных". Суть "зачистки" — через безнаказанное хамство некоторых активных участников форума, подкреплённое их статусом модеров.

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


V>>Не переиграешь потом ничего в ядре, инерционность будет большая.

WH>Ядро уже не один раз переделывалось без изменения синтаксиса. И всё продолжало работать.

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


V>>>>Там вообще своё восстановление написать можно, бо кишки Бизона открыты.

WH>>>Ты вообще понимаешь какой неадекват ты тут несёшь?
V>>Да ну? Это я, значит, по обрывкам информации ориентируюсь и считаю, что владею ею? ))
WH>1)Именно ты.
WH>2)Как эти две твои фразы соотносятся между собой не ясно.

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


WH>>>Я вернул то что ты потёр. А теперь попробуй объяснить, как одно связано с другим?

V>>Ты мне можешь один раз прямо ответить на прямой вопрос — ты в ВУЗ-е учился на программиста или нет?
WH>Успокойся. Про регулярные выражения я знаю намного больше чем ты.

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


V>>В результирующем ДКА пометка конечного состояния (выхода) должна стоять только у целевых лексем, ес-но.

V>>Т.е. в исходном описании грамматики необходимо как-то особо помечать целевые правила.
WH>1)В нитре всё прекрасно работает без всяких пометок

В нитре у тебя нет отдельного описания лексера, вестимо. Поэтому "само".
А если нужен только лексер?
Чудес не бывает, если возможность описания промежуточных правил присутствует, то они объявляются как-то иначе.

Например, в одном из проектов я использовал разные ключевые слова:
rule — как алиас правилу;
lexem — как описание целевой лексемы.

Пример будет примерно такой:
rule decdigits = ('0' |.. '9')+;
lexem decnum = decdigits;
lexem floatnum = decnum '.' {decnum} | '.' decnum;

У парсера тут будет только три выходных состояния: ошибка, decnum и floatnum.
Т.е. никакого decdigits.


WH>Вот такое вот вычитание одного бесконечного множества из другого.


Ну и чего тогда ты пишешь вот такое:

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


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


WH>И это просто частный случай более общей операции.

WH>
...
WH>


Я прекрасно знаю, как строить ДКА для операции вычитания.
Собсно, это банальная операция над множеством, где такую операцию преподают на 1-м курсе по предмету вышка.
Точно так же как знаю, что не всегда можно при этом получить ДКА (в сочетании с другими конфликтующими правилами, например).


WH>2)Как это связано с ручным описанием восстановления не ясно.


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


V>>В общем, для адекватного обсуждения требовалось желание собеседников "втыкать" в тему.

WH>Мы предварительно посмотрели тесты производительности. И там всё было очень печально.

Не пойму логики.
Ты же взял Эрли, а там всё было еще печальнее в тестах?
Значит, надо было смотреть не только тесты?
Может, там руки кривые, т.е. реализация не ахти?
Такое часто происходит в академических проктах.
Потому что они считают стоимость разбора в кол-ве примитивных операций на символ.
И правильно делают, кста.
Потому что при прочих равных надо выбирать тот алгоритм, который имеет меньше примитивных операций на символ.
"При прочих равных" — это при возможности одинаково допилить эффективность этих примитивных операций.

Более того. В тех академических исходниках, которые я видел по GLR — там стояли даже счетчики статистики.
Да одно лишь обслуживание этих счетчиков вдоль иерархии, которая должна быть иммутабельна в течении довольно длинной цепочки символов — это всё обходится дороже, чем сам парсинг.

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


WH>Да все тесты ГЛР имеют похожие цифры.


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


V>>Пакрат запоминает удачные ветки разбора, Эрли все. Это принципиально. Держим это в уме и пытаемся ставить задачу.

WH>Классический пакрат для каждой позиции в тексте запоминает результат разбора всех правил грамматики для этой позиции.

Учись пользоваться общепринятой терминологией.
Описанное верно для "предпросмотра" строго на 1, т.е. имея на руках текущую лексему.


WH>Естественно такую дурь на практике никто не реализует.


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


WH>Он так был сформулирован только для доказательства линейности.

WH>Но это просто очередная демонстрация понимания тобой предмета.

Пфф...
Я понимаю особенности Пакрата куда как лучше, чем ты особенности GLR.

Причем, вот даже сейчас я через всего две фразы показал ЛЮБОМУ читателю со стороны суть происходящего.
А вы и за 8 не смогли кратко пояснить особенности вашего технического решения.
Потому что надо пользоваться общепринятыми понятиями, а не "а вот тут оно у нас по автомату бежит". ))

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

Просто мне/нам приходится прикладывать определённые усилия, чтоб "понимать" хоть что-то из твоих разрозненных мутных намеков в разные годы.
Даже огромный вводный пост Влада по PEG — там ровным счётом ноль инфы:
http://www.rsdn.org/forum/philosophy/3862121
Загадочные вы наши.

Обрати внимание, что я более чем доступно описываю суть своих технических решений.
Потому что иначе вообще не имеет смысла раскрывать рот.
Если ты НЕ МОЖЕШЬ донести до коллег информацию, то лучше вообще молчать, чем потом строить из себя обиженного на весь белый свет, что, мол, "гений был не понят", ы-ы-ы. )))


V>>А у тебя что? У тебя ровно наоборот — взят неадекватный алгоритм для невалидного исходника и шустрый для валидного.

WH>А у меня с этим нет никаких проблем. Всё прекрасно работает.
WH>Ибо 99% исходника корректно и будет разобрано основным алгоритмом.
WH>И я тебе уже об этом говорил. Но ты же не меня слушаешь, а голоса в голове.

Ну вот слона-то ты и не заметил. ))
Я работаю с таким языком, где одна ошибка в начале h-файла делает весь остальной файл невалидным. Ну и еще десятки зависимых впридачу.
Вроде бы я не скрываю, какой у меня основной язык по работе.


V>>Но этого мало — по твоим словам выходит так, что в случае ошибки парсинг запускается повторно. И это основной сценарий в процессе той самой активной набивки текста???

WH>Так всё же запомнено.

Так и для GLR "все запомнено".


WH>Так что ничего из того что уже отпарсено не перепарсивается.

WH>Нужно только несколько раз в таблицу мемоизации заглянуть.
WH>Ты понимаешь, что с таким захлёбом о наносекундах говоришь? При том что время реакции человека 100 миллисекунд.

Так тебя не поймешь. То тебе одной миллисекунды на десятки килобайт мало (средний размер файла исходника), то теперь "взахлёб говоришь".
Смишно.
За 100 миллисекунд у меня парсится несколько метров.


WH>Память эрли кушает там, где есть куча неоднозначностей.

WH>Но GLR будет делать то же самое.

ЧТД, не понимаешь.
GLR оперативно отсекает неоднозначности.
Он практически никогда не растёт в ширину даже на сколь угодно длинных цепочках.
Собсно — это даже где-то вызов, придумать такую грамматику, где GLR будет вести себя так же как Эрли.
Хотя, теоретически они работают, считай, одинаково — вид сбоку.
Там всё отличие именно в возможности эффективного переиспользования памяти на практических задачах.


WH>А там, где неоднозначностей нет там всё линейно.


И опять у тебя ошибка.
Потому что "неоднозначностей" с т.з. LL(1), если Эрли распараллеливает LL(1) (например, распараллеливает прямую интерпретацию БНФ)
Увы, класс грамматик LL(1) слишком узок, поэтому для более сложных грамматик будут неоднозначности даже там, где их нет, скажем, для LL(2).


WH>Особенно это касается моего варианта Эрли у которого в правой части правил не последовательность, а произвольный автомат. Ибо вместо бестолковой рекурсии он просто бежит по автомату.


По LL(k) можно построить автомат, и?
Правильно ли я тебя понимаю, что ты построил Эрли не на основе распараллеливания LL(1) как в исходном алгоритме, а на основе LL(k)?
А чему равно k?


V>>Даже в том обсуждении про БНФ ты не понял очевидной вещи — это возможности автоматической трансформации грамматик.

WH>Не нужно. Просто не нужно если алгоритм и так работает.

При разработке сложного языка — нужно обязательно.


V>>А людям для обработки нужно AST, которое удобное для банального понимания.

V>>Но часто приходится подвергать грамматику факторизации/коррекции и получается уход от первоначальной идеи.
V>>С AST по изменённой грамматике бывает работать неудобно.
WH>А в случае с нитрой не приходится.
WH>Прикинь.
WH>Ты описываешь грамматику так как удобно, и она просто работает.

Если ты про описание ПЕГ — то это НЕ удобно для огромного класса грамматик.
Еще раз, медленно — мне удобней для обработки такое AST, которое построено на честном choice.
Т.е. НЕ зависит от последовательности упоминания правил.
Потому что такое AST будет самым простым, т.е. наиболее выразительным.
Re[30]: Опциональные типы
От: WolfHound  
Дата: 14.03.17 12:02
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>Ты эпично слился с ЗТ в С++. Если оттрекать весь спор с самого начала — ни одно моё утверждение не было ошибочным.


Тип — это именованное множество значений.
Множество значений ЗТ зависит от значения.
На С++ так нельзя. И на хаскеле так тоже нельзя.
Всё.

V>Ваша Нитра идёт на одну всего платформу, т.е. её потенциальный рынок тоже 2-3 построенных на ней ИДЕ.

Наша нитра уже сейчас может быть встроена в любую ИДЕ на винде, маке и линухе.
Ибо движок живёт в отдельном процессе и общается с ИДЕ по очень тонкому протоколу.

V>Любой тулкит ASN.1 — это генератор парсеров.

А ещё сериализаторов и биндингов к языкам.
А если бинарный формат нужно парсить ANTLR'ом то тут явный неадекват.

V>Дурацкий вопрос.

V>Ты пробовал читать схемы электрические принципиальные через net-list?
V>А карту местности через список координат населённых пунктов?
V>Ну вот попробуй.
Какое это отношение имеет к грамматике? Да никакого.

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

Ну это проблемы генератора парсеров если там так приходится приоритеты задавать.
В нормальных инструментах это делают вот так
    precedence Additive:
    | add        = expr sm '+' sm expr { override Value = Expr1.Value() + Expr2.Value(); }
    | sub        = expr sm '-' sm expr { override Value = Expr1.Value() - Expr2.Value(); }

    precedence Multiplicative:
    | mul        = expr sm '*' sm expr { override Value = Expr1.Value() * Expr2.Value(); }
    | div        = expr sm '/' sm expr { override Value = Expr1.Value() / Expr2.Value(); }
    | mod        = expr sm '%' sm expr { override Value = Expr1.Value() % Expr2.Value(); }

    precedence Power:
    | pow        = expr sm '^' sm expr right-associative
                                       { override Value = System.Math.Pow(Expr1.Value(), Expr2.Value()); }

    precedence Unary:
    | neg        = '-' expr            { override Value = -Expr.Value(); }

В крайнем случае можно использовать числа.

А вот это:
input    ::= ws expr ws eoi;

expr    ::= ws powterm [{ws '^' ws powterm}];
powterm    ::= ws factor [{ws ('*'|'/') ws factor}];
factor    ::= ws term [{ws ('+'|'-') ws term}];
term    ::= '(' ws expr ws ')' | '-' ws expr | number;

Звиздец неадекватный.
Поддерживать такое невозможно.
А про добавление операторов про которые не знал разработчик основной грамматики вообще можно забыть.

V>И не надо мне опять про набивший оскомину ПЕГ, где приоритет задаётся явно через "правильную" очередность описания правил.

Приоритетный выбор не имеет никакого отношения к приоритету операций.

V>Мне надо без всякой "правильной" очередности.

V>Мне надо честный choice.
Тебе ничего не надо. Ибо ты не понимаешь, что там происходит, а значит не можешь осмысленно выбрать.

V>Дерево — это и есть графическое представление графа (масло масляное, но ничего не поделать).

V>А чего тогда спрашиваешь "зачем"?
Я спрашиваю нахрена мне графическое представление грамматики?
Дерево разбора и грамматика — это разные вещи.

WH>>Что тебе даст стрелка, идущая мимо expression по сравнению со знаком "?" стоящим после expression?

V>Покажет, правильно ли я поставил закрывающие скобки.


V>>>>>Там вообще своё восстановление написать можно, бо кишки Бизона открыты.

WH>>>>Ты вообще понимаешь какой неадекват ты тут несёшь?
V>>>Да ну? Это я, значит, по обрывкам информации ориентируюсь и считаю, что владею ею? ))
WH>>1)Именно ты.
WH>>2)Как эти две твои фразы соотносятся между собой не ясно.
V>Потому что ты выдаешь "окончательные суждения" именно на основе неполной информации.
V>Специалист обязан во всём сомневаться и сам всё проверять.
V>Считай, что это религия такая. Обязательная к принятию догма.
Ты опять облажался и пытаешься соскочить с вопроса.

V>Ну так в другой раз переспроси, если некая терминология не понятна, а не накидывайся сходу.

Ну так я и спрашиваю. Как ручное описание алгоритма восстановления (что само по себе дикий неадекват) относится к целевым правилам в лексере?

V>В бизоне описываются только парсер, лексер для него описывается отдельно через flex.

V>Т.е. ты этого не знал, но опять бежишь на меня наезжать.
V>Теперь-то хоть прояснилось?
Это вообще к делу не относится.
Ты опять наслушался голосов и тебя понесло чёрт знает куда.

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

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

V>Ты же взял Эрли, а там всё было еще печальнее в тестах?

Ты меня совсем не слушаешь. Эрли работает на 1% кода и только в случае если код сломан.

V>>>Пакрат запоминает удачные ветки разбора, Эрли все. Это принципиально. Держим это в уме и пытаемся ставить задачу.

WH>>Классический пакрат для каждой позиции в тексте запоминает результат разбора всех правил грамматики для этой позиции.
V>Учись пользоваться общепринятой терминологией.
V>Описанное верно для "предпросмотра" строго на 1, т.е. имея на руках текущую лексему.
Что за бред опять. Ты вообще про пакрат читал? Похоже, что нет. Или вместо чтения слушал голоса.
Пакрат работает посимвольно без всякого предпросмотра.

V>Причем, вот даже сейчас я через всего две фразы показал ЛЮБОМУ читателю со стороны суть происходящего.

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

V>Если ты НЕ МОЖЕШЬ донести до коллег информацию, то лучше вообще молчать, чем потом строить из себя обиженного на весь белый свет, что, мол, "гений был не понят", ы-ы-ы. )))

Вот и молчи.
Ибо информации у тебя нет.
Совсем.
Только трёп, который противоречит всем независимым тестам.
В прочем от тебя вообще никаких тестов не было.

V>Ну вот слона-то ты и не заметил. ))

V>Я работаю с таким языком, где одна ошибка в начале h-файла делает весь остальной файл невалидным. Ну и еще десятки зависимых впридачу.
V>Вроде бы я не скрываю, какой у меня основной язык по работе.
Только все эти ошибки отлавливаются не парсером. А кодом, который работает после парсера.

WH>>Так что ничего из того что уже отпарсено не перепарсивается.

WH>>Нужно только несколько раз в таблицу мемоизации заглянуть.
WH>>Ты понимаешь, что с таким захлёбом о наносекундах говоришь? При том что время реакции человека 100 миллисекунд.
V>Так тебя не поймешь. То тебе одной миллисекунды на десятки килобайт мало (средний размер файла исходника), то теперь "взахлёб говоришь".
V>Смишно.
V>За 100 миллисекунд у меня парсится несколько метров.
Что ты опять несёшь? Ты вообще читаешь что написано?
Или отвечаешь на то что тебе голоса в голове напели?

WH>>Особенно это касается моего варианта Эрли у которого в правой части правил не последовательность, а произвольный автомат. Ибо вместо бестолковой рекурсии он просто бежит по автомату.

V>По LL(k) можно построить автомат, и?
V>Правильно ли я тебя понимаю, что ты построил Эрли не на основе распараллеливания LL(1) как в исходном алгоритме, а на основе LL(k)?
V>А чему равно k?
Неправильно.
1)В Эрли вообще нет никакого предпросмотра. Ты даже основной алгоритм не понял. А он же прост как пробка. Он даже проще чем LL(1).
2)Ты же вообще не читаешь. Ты голоса в голове слушаешь.
У меня Эрли не по BNF работает, а по надмножеству EBNF без переписывания грамматики в BNF.
3)Что характерно, когда я обсуждал свою модификацию Эрли с человеком, который действительно занимается разработкой GLR парсеров он понял, что я сделал после слов "автомат вместо последовательности".
Всё объяснение секунд 10-20 заняло.

V>>>Даже в том обсуждении про БНФ ты не понял очевидной вещи — это возможности автоматической трансформации грамматик.

WH>>Не нужно. Просто не нужно если алгоритм и так работает.
V>При разработке сложного языка — нужно обязательно.
Сложного это какого?
Назови имя.
C# это сложный язык или нет?
И мы сейчас говорим исключительно про парсер. И в этом контексте C# намного сложнее C++.

V>Если ты про описание ПЕГ — то это НЕ удобно для огромного класса грамматик.

V>Еще раз, медленно — мне удобней для обработки такое AST, которое построено на честном choice.
V>Т.е. НЕ зависит от последовательности упоминания правил.
V>Потому что такое AST будет самым простым, т.е. наиболее выразительным.
1)Форма АСТ не зависит от того есть приоритетный выбор или нет.
2)Нитра никогда не была ПЕГ'ом. В нитре никогда не было приоритетного выбора. И я об этом уже говорил. Но ты же не читаешь, а голоса слушаешь.
При этом нитра пакрат. Ибо пакратом можно парсить не только ПЕГ.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[28]: Опциональные типы
От: alex_public  
Дата: 15.03.17 07:20
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ты вообще представляешь себе объём этой работы?

WH>Одну и ту же грамматику этим парсерам не скормить. И я говорю не про изменение синтаксиса, хотя это само по себе большой объём работы, а про то что у них алгоритмы разные.
WH>Тут придётся въезжать в особенности каждого алгоритма и трансформировать под него грамматику. Иначе тест будет нечестным.
WH>При этом тестировать на маленькой грамматике бесполезно.
WH>Короче это развлекалово ни на один месяц.

Кстати, тут на C++ форуме всплыла темка про парсеры (http://rsdn.org/forum/cpp.applied/6720612.flat
Автор: SL
Дата: 09.03.17
) и я нашёл в ней (ну или далее по ссылкам) много довольно любопытной информации.

Во-первых про различные парсеры для C++: antlr4 теперь работает для C++ (https://github.com/antlr/antlr4/tree/4.6/runtime/Cpp/demo), ещё один универсальный (многоязычный) инструмент такого типа под названием Coco/R (http://ssw.jku.at/Coco/), ещё пара C++ проектов в данной области (https://jeffreykegler.github.io/Marpa-web-site/ и https://github.com/vnmakarov/yaep).

А во-вторых в последнем проекте я прямо на первой же странице увидел те самые тесты, про которые говорил. Причём в качестве грамматики они использовали не абы что, а язык C. Так что они смогли добавить к тестами парсер из gcc. Так вот самое забавное, что тот самый bison (ну точнее там был yacc, но не суть) показал себя там быстрее всех, лучше даже парсера gcc. )

P.S. Особенно забавным в контексте дискуссии выше мне показалась фраза из описания последнего проекта:

It is sufficiently fast and does not require much memory. This is the fastest implementation of the Earley parser which I know of. If you know a faster one, please send me a message. It can parse 300K lines of C program per second on modern computers and allocates about 5MB memory for 10K line C program.

Отредактировано 15.03.2017 7:28 alex_public . Предыдущая версия .
Re[29]: Опциональные типы
От: WolfHound  
Дата: 15.03.17 10:15
Оценка:
Здравствуйте, alex_public, Вы писали:

_>А во-вторых в последнем проекте я прямо на первой же странице увидел те самые тесты, про которые говорил. Причём в качестве грамматики они использовали не абы что, а язык C.

Это и есть абы что.
У С очень простая грамматика.

_>Так что они смогли добавить к тестами парсер из gcc. Так вот самое забавное, что тот самый bison (ну точнее там был yacc, но не суть) показал себя там быстрее всех, лучше даже парсера gcc. )

Ну да LALR работает быстро. Кто бы спорил.
Но тут про GLR разговор. А это совсем другая история.

_>

_>It is sufficiently fast and does not require much memory. This is the fastest implementation of the Earley parser which I know of. If you know a faster one, please send me a message. It can parse 300K lines of C program per second on modern computers and allocates about 5MB memory for 10K line C program.

Тут нужно долго разбираться что там происходит.
Но беглый просмотр показал, что код однопоточный. Это фатальный недостаток для промышленного использования.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[30]: Опциональные типы
От: vdimas Россия  
Дата: 17.03.17 22:22
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Тут нужно долго разбираться что там происходит.

WH>Но беглый просмотр показал, что код однопоточный.

И опять демагогия.
Для целей выяснения вычислительной сложности это не имеет никакого значения.
Re[30]: Опциональные типы
От: vdimas Россия  
Дата: 17.03.17 22:34
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Тут нужно долго разбираться что там происходит.


http://dl.acm.org/citation.cfm?id=13326&amp;dl=
Ссылка интересная:

LR parsers can be made to run 6 to 10 times as fast as the best table-interpretive LR parsers.

1986 г.
Прямая кодогенерация дала в 6-10 раз ускорение в сравнении с интерпретацией таблицы переходов.
Re[31]: Опциональные типы
От: vdimas Россия  
Дата: 18.03.17 07:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

V>>Ты эпично слился с ЗТ в С++. Если оттрекать весь спор с самого начала — ни одно моё утверждение не было ошибочным.

WH>
WH>Тип — это именованное множество значений.
WH>Множество значений ЗТ зависит от значения.
WH>На С++ так нельзя. И на хаскеле так тоже нельзя.
WH>Всё.

Наша песня хороша, начинай сначала?
Я уже давал ссылки на одну из теорий типов, где всё является типами, т.е. все участники этой иерархии однородны и просто описываются отношениями друг с другом.
В этом случае подобные иерархии схлопываются.
В любом случае, нам вся эта кухня нужна не для терминологического спора, а для выяснения класса задач, которые можно готовить на этой кухне.
Было показано, что через трюк однозначного отображения значений на типы при поддержке полноценного параметрического полиморфизма можно решать тот класс задач, который по зубам только системам с ЗТ.
Вот теперь всё.
Остальное — это лишь демонстрация непонимания.


V>>Ваша Нитра идёт на одну всего платформу, т.е. её потенциальный рынок тоже 2-3 построенных на ней ИДЕ.

WH>Наша нитра уже сейчас может быть встроена в любую ИДЕ на винде, маке и линухе.
WH>Ибо движок живёт в отдельном процессе и общается с ИДЕ по очень тонкому протоколу.

Пусть тогда в Сети где-то живет, какая уже тогда разница?
Даёшь ферму Nitra-сервисов? ))


V>>Любой тулкит ASN.1 — это генератор парсеров.

WH>А ещё сериализаторов и биндингов к языкам.
WH>А если бинарный формат нужно парсить ANTLR'ом то тут явный неадекват.

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


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

WH>В нормальных инструментах это делают вот так
WH>
...
WH>

WH>В крайнем случае можно использовать числа.

ЧТД. Прибили гвоздями к некоторой семантике бинарных операций.


V>>И не надо мне опять про набивший оскомину ПЕГ, где приоритет задаётся явно через "правильную" очередность описания правил.

WH>Приоритетный выбор не имеет никакого отношения к приоритету операций.

Я про применение правил вообще, а не только про бинарные операции.


V>>Мне надо без всякой "правильной" очередности.

V>>Мне надо честный choice.
WH>Тебе ничего не надо. Ибо ты не понимаешь, что там происходит, а значит не можешь осмысленно выбрать.

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


WH>Я спрашиваю нахрена мне графическое представление грамматики?


Тебе не надо, мне надо.
Я большие массивы информации лучше читаю в виде карт-схем.


WH>>>Что тебе даст стрелка, идущая мимо expression по сравнению со знаком "?" стоящим после expression?

V>>Покажет, правильно ли я поставил закрывающие скобки.
WH>

ЧТД. Нечего ответить.
Речь о скобке в исходном описании грамматики, а не во входных данных для разбора.


V>>Потому что ты выдаешь "окончательные суждения" именно на основе неполной информации.

V>>Специалист обязан во всём сомневаться и сам всё проверять.
V>>Считай, что это религия такая. Обязательная к принятию догма.
WH>Ты опять облажался и пытаешься соскочить с вопроса.

Ладно. Твоя демагогия надоела.

Смотри, что ты делаешь.
Ты взял некие два заведомо не самых эффективных алгоритма парсинга — Пакрат и Эрли.
Затем ты допилил их до более-менее приемлемой эффективности.
Молодец ты в этом месте? — Молодец.

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

Вот еще чуток копнул, вижу алгоритм NR GRL.
Вот данные по грамматике языка С в кол-ве операций обхода для некоего тестового примера:
GLR на основе LR(0) — 42707
GLR на основе LR(1) — 30754
RNGLR на основе LR(0) — 5184
RNGLR на основе LR(1) — 4450

Разница на порядок в вычислительной сложности для С.

А теперь на специальном "патологическом" для GLR примере:
GLR на основе LR(0) — 334831502
GLR на основе LR(1) — 1000001
RNGLR на основе LR(0) — 499500
RNGLR на основе LR(1) — 999

Искать Evaluating-GLR-parsing-algorithms_2006_Science-of-Computer-Programming.pdf


V>>Ну так в другой раз переспроси, если некая терминология не понятна, а не накидывайся сходу.

WH>Ну так я и спрашиваю. Как ручное описание алгоритма восстановления (что само по себе дикий неадекват) относится к целевым правилам в лексере?

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


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

V>>Потому что тут чисто человеческий фактор — не до любых правил имеет смысл восстанавливаться.
WH>Вот только о чудо. Нитра без этого работает.

Еще раз, медленно.
В нитре лексер и парсер описываются совместно.
Поэтому, ты имеешь возможность восстанавливаться посимвольно.


V>>Ты же взял Эрли, а там всё было еще печальнее в тестах?

WH>Ты меня совсем не слушаешь. Эрли работает на 1% кода и только в случае если код сломан.

1. У меня в процессе активной набивки код практически всегда сломан.
2. Всё равно выбор Эрли из других обобщённых не обоснован.


V>>>>Пакрат запоминает удачные ветки разбора, Эрли все. Это принципиально. Держим это в уме и пытаемся ставить задачу.

WH>>>Классический пакрат для каждой позиции в тексте запоминает результат разбора всех правил грамматики для этой позиции.
V>>Учись пользоваться общепринятой терминологией.
V>>Описанное верно для "предпросмотра" строго на 1, т.е. имея на руках текущую лексему.
WH>Что за бред опять. Ты вообще про пакрат читал? Похоже, что нет. Или вместо чтения слушал голоса.
WH>Пакрат работает посимвольно без всякого предпросмотра.

Да что ты несешь-то уже, боже пипец какое это чудовищное нубство, а-а-а-а-а-аа-а-а.
Вот ты себя и закопал только что.

Показываю в два приёма:
Ты алгоритм парсинга LL(1) по ДКА смотрел?
А с Пакратом сравнивал (построение такого ДКА)?
А есть ли в коде парсера по ДКА, построенному для LL(1) явная операция "предпросмотра"?
Нет? А в самом исходном алгориме есть.
Как так?

Кароч, всё ясно.
Пфф и наше вам с кисточкой...

==========
(боже, с кем я спорил столько времени....)
Отредактировано 18.03.2017 7:32 vdimas . Предыдущая версия .
Re[31]: Опциональные типы
От: vdimas Россия  
Дата: 18.03.17 11:11
Оценка: :))
Здравствуйте, WolfHound, Вы писали:

V>>Описанное верно для "предпросмотра" строго на 1, т.е. имея на руках текущую лексему.

WH>Что за бред опять. Ты вообще про пакрат читал?

В общем, ты НЕ понимаешь, как работает Пакрат и как строится ДКА для LL(k).

"Предпросмотр" для от 0-ля до k преобразуется при построении автомата (или мемоизации в Пакрате) в "отставание".
Т.е., последовательность T(0), T(1), T(2) можно рассматривать и так:
T(-2), T(-1), T(0).
Вот как строится детерминированный разбор для LL(k) парсеров.

В позиции, например, T(-2) у нас еще имеется неоднозначность, которая может быть решена в точке T(0).
Вот так работает классический Пакрат.
Заполнение таблицы мемоизации для него:

We can avoid computing any of these intermediate results multiple times by storing them in a table. The table has one row for each of the four parse functions and one column for each distinct position in the input string. We fill the table with the results of each parse function for each input position, starting at the right end of the input string and working towards the left, column by column.


Пример оттуда же:
pAdditive d = alt1 where
-- Additive <- Multitive ’+’ Additive
  alt1 = case dvMultitive d of
    Parsed vleft d’ ->
      case dvChar d’ of
        Parsed ’+’ d’’ ->
          case dvAdditive d’’ of
            Parsed vright d’’’ ->
              Parsed (vleft + vright) d’’’
              _ -> alt2
            _ -> alt2
        _ -> alt2

Просмотр "назад" на 2 символа.

Оттуда же:

As Pepper points out [17], LR parsing can be viewed simply as LL parsing with the grammar rewritten so as to eliminate left recursion and to delay all important parsing decisions as long as possible. The result is that LR provides more flexibility in the way grammars can be expressed, but no actual additional recognition power.

Но вот видно, что человек прекрасно понимает проблематику.
А ты нет.
Выделенное важно.
Re[31]: Опциональные типы
От: WolfHound  
Дата: 18.03.17 11:27
Оценка:
Здравствуйте, vdimas, Вы писали:

WH>>Тут нужно долго разбираться что там происходит.

WH>>Но беглый просмотр показал, что код однопоточный.
V>И опять демагогия.
V>Для целей выяснения вычислительной сложности это не имеет никакого значения.
1)Опять голоса в голове. Я имел в виду ровно то что сказал и ничего больше.
2)Кстати зачем ты стёр это:

Это фатальный недостаток для промышленного использования.

Пытаешься вести фигурную резьбу по цитатам и ещё обвиняешь меня в демагогии.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Опциональные типы
От: WolfHound  
Дата: 18.03.17 11:27
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Наша песня хороша, начинай сначала?

Продолжаешь спорить с определениями? Ну-ну.

V>>>Ваша Нитра идёт на одну всего платформу, т.е. её потенциальный рынок тоже 2-3 построенных на ней ИДЕ.

WH>>Наша нитра уже сейчас может быть встроена в любую ИДЕ на винде, маке и линухе.
WH>>Ибо движок живёт в отдельном процессе и общается с ИДЕ по очень тонкому протоколу.
V>Пусть тогда в Сети где-то живет, какая уже тогда разница?
V>Даёшь ферму Nitra-сервисов? ))
Примерно всё что нужно уже готово.
Если будет спрос можно будет за несколько недель недостающий код написать.

V>Не отмазывайся, ты утверждал, что генератор парсера для бинарного формата — это бред.

V>Бинарные форматы, так же как и текстовые, могут иметь весьма развесистую грамматику.
Неадекват.
И бинарные форматы с развесистой грамматикой это и есть неадкват.

WH>>В крайнем случае можно использовать числа.

V>ЧТД. Прибили гвоздями к некоторой семантике бинарных операций.
Ты даже не попытался понять, что там происходит и делаешь выводы из того что тебе голоса напели.
Там полноценный "Top down operator precedence" Pratt, Vaughan.
А бинарные и унарные операторы только сахар, ибо используются примерно в 100% случаях.
А так там можно и что-то посложнее.
    precedence Choice:
    | Choice                  = LeftRule=RegexExpression ^ Choice sm RightRules=("|" RegexExpression ^ Choice)+
    
    precedence Sequence:
    | Sequence                = LeftRule=RegexExpression ^ Sequence sm RightRules=(RegexExpression ^ Sequence)+

Вот так описываются N'арные операторы.
В данном случае оператор пробел имеет больший приоритет чем оператор |.

V>>>И не надо мне опять про набивший оскомину ПЕГ, где приоритет задаётся явно через "правильную" очередность описания правил.

WH>>Приоритетный выбор не имеет никакого отношения к приоритету операций.
V>Я про применение правил вообще, а не только про бинарные операции.
Ты даже не понимаешь, что это не одно понятие, а два разных.
1)Приоритетный выбор.
2)Приоритет операторов.
Имеют между собой примерно столько же общего как
1)Ключ из которого вода течёт.
2)Ключ которым замок открывают.

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

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

WH>>Я спрашиваю нахрена мне графическое представление грамматики?

V>Тебе не надо, мне надо.
V>Я большие массивы информации лучше читаю в виде карт-схем.
Может тебе и код на С в виде диаграммы нужно?

WH>>>>Что тебе даст стрелка, идущая мимо expression по сравнению со знаком "?" стоящим после expression?

V>>>Покажет, правильно ли я поставил закрывающие скобки.
WH>>
V>ЧТД. Нечего ответить.
V>Речь о скобке в исходном описании грамматики, а не во входных данных для разбора.
А что вообще на этот бред ответить можно?
Это настолько высосано из пальца что дальше просто некуда.

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

Я утверждаю немного другое: Все опубликованные тесты GLR говорят о том, что он тормозит.
Ты можешь создать тест, который покажешь, что GLR крут.
Тогда ты будешь молодцом. А до тех пор будешь треплом.

V>Вот еще чуток копнул, вижу алгоритм NR GRL.

V>Вот данные по грамматике языка С в кол-ве операций обхода для некоего тестового примера:
Мне не нужны попугаи.
Мне нужны корректные тесты производительности, которые я могу запустить.
А то мой парсер даёт разброс на грамматике C# от 3 до 100 метров в секунду на разных файлах.
Так что подбором данных можно очень много накрутить.

V>>>Ну так в другой раз переспроси, если некая терминология не понятна, а не накидывайся сходу.

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

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

V>>>Потому что тут чисто человеческий фактор — не до любых правил имеет смысл восстанавливаться.
WH>>Вот только о чудо. Нитра без этого работает.
V>Еще раз, медленно.
V>В нитре лексер и парсер описываются совместно.
V>Поэтому, ты имеешь возможность восстанавливаться посимвольно.
Ты чего пять несёшь? Причем тут посимвольное восстановление?
Что тебе опять голоса напели?

V>>>Ты же взял Эрли, а там всё было еще печальнее в тестах?

WH>>Ты меня совсем не слушаешь. Эрли работает на 1% кода и только в случае если код сломан.
V>1. У меня в процессе активной набивки код практически всегда сломан.
Ещё раз. Именно в этом случае Эрли работает на 1% кода.
Когда код без ошибок Эрли вообще не работает.

V>2. Всё равно выбор Эрли из других обобщённых не обоснован.

Ты не можешь судить. Ибо совершенно не понимаешь, что там происходит.

V>А есть ли в коде парсера по ДКА, построенному для LL(1) явная операция "предпросмотра"?

V>Нет? А в самом исходном алгориме есть.
V>Как так?
Вот кусок кода который сгенерировал Coco/R который является генератором LL(1) парсеров.
Код вида if (la.kind == 14) и есть предпросмотр.
    void RelOp(out Op op) {
        op = Op.EQU; 
        if (la.kind == 14) {
            Get();
        } else if (la.kind == 15) {
            Get();
            op = Op.LSS; 
        } else if (la.kind == 16) {
            Get();
            op = Op.GTR; 
        } else SynErr(30);
    }

    void Factor(out int type) {
        int n; Obj obj; string name; 
        type = undef; 
        if (la.kind == 1) {
            Ident(out name);
            obj = tab.Find(name); type = obj.type;
            if (obj.kind == var) {
            if (obj.level == 0) gen.Emit(Op.LOADG, obj.adr);
            else gen.Emit(Op.LOAD, obj.adr);
                         } else SemErr("variable expected"); 
        } else if (la.kind == 2) {
            Get();
            n = Convert.ToInt32(t.val); 
            gen.Emit(Op.CONST, n); type = integer; 
        } else if (la.kind == 4) {
            Get();
            Factor(out type);
            if (type != integer) {
             SemErr("integer type expected"); type = integer;
            }
            gen.Emit(Op.NEG); 
        } else if (la.kind == 5) {
            Get();
            gen.Emit(Op.CONST, 1); type = boolean; 
        } else if (la.kind == 6) {
            Get();
            gen.Emit(Op.CONST, 0); type = boolean; 
        } else SynErr(31);
    }

Ну и кто тут себя закопал?
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Опциональные типы
От: WolfHound  
Дата: 18.03.17 12:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Описанное верно для "предпросмотра" строго на 1, т.е. имея на руках текущую лексему.

WH>>Что за бред опять. Ты вообще про пакрат читал?
V>В общем, ты НЕ понимаешь, как работает Пакрат и как строится ДКА для LL(k).
И как я умудрился его написать, не понимая, как он работает?

V>

V>We can avoid computing any of these intermediate results multiple times by storing them in a table. The table has one row for each of the four parse functions and one column for each distinct position in the input string. We fill the table with the results of each parse function for each input position, starting at the right end of the input string and working towards the left, column by column.

Все функции в пакрате имеют вот такие пролог и эпилог
int ParseSomeRule(int startPos, string text)
{
  int newPos;
  if (memoize.TryGetValue(new Key(SomeRuleID, startPos), out newPos))
    return newPos;

  //Разбор

  memoize.Add(new Key(SomeRuleID, startPos), newPos);
  return newPos;
}

Разбор альтернатив выглядит вот так (приоритетный выбор)
  newPos = -1;

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative1(startPos, text);

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative2(startPos, text);

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative3(startPos, text);

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative4(startPos, text);

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative5(startPos, text);

  if (newPos < 0)
    newPos = ParseSomeRuleAlternative6(startPos, text);

Разбор последовательности вот так
newPos = startPos;
newPos = ParseSome1(newPos, text);
if (newPos >= 0)
{
    newPos = ParseSome2(newPos, text);
    if (newPos >= 0)
    {
        newPos = ParseSome3(newPos, text);
        if (newPos >= 0)
        {
            newPos = ParseSome4(newPos, text);
            if (newPos >= 0)
            {
                newPos = ParseSome5(newPos, text);
            }
        }
    }
}

Каждое правило может съёсть произвольное колличество терминалов.
Так что никакого отставания на 2 символа в пакрате нет в принципе.

V>Оттуда же:

V>

V>As Pepper points out [17], LR parsing can be viewed simply as LL parsing with the grammar rewritten so as to eliminate left recursion and to delay all important parsing decisions as long as possible. The result is that LR provides more flexibility in the way grammars can be expressed, but no actual additional recognition power.

V>Но вот видно, что человек прекрасно понимает проблематику.
V>А ты нет.
V>Выделенное важно.
Только для LL(k) vs LR(k) случая. И в данном обсуждении это оффтопик. И ты ещё пытаешься меня в демагогии обвинять.
Для GLL, GLR, Earley итп это не важно. Они неторопливо отпарсят любую грамматику.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[30]: Опциональные типы
От: alex_public  
Дата: 19.03.17 17:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

_>>А во-вторых в последнем проекте я прямо на первой же странице увидел те самые тесты, про которые говорил. Причём в качестве грамматики они использовали не абы что, а язык C.

WH>Это и есть абы что.
WH>У С очень простая грамматика.

Ну так и замечательно. Это же было бы странно для какого-то теста проделывать реальную сложную работу. А тут всё просто идеально: и простая грамматика и при этом одновременно один из самых популярных языков. Да и легко подобрать реальный тест (как сделано в обсуждаемом случае) с мегабайтным исходником.

_>>Так что они смогли добавить к тестами парсер из gcc. Так вот самое забавное, что тот самый bison (ну точнее там был yacc, но не суть) показал себя там быстрее всех, лучше даже парсера gcc. )

WH>Ну да LALR работает быстро. Кто бы спорил.
WH>Но тут про GLR разговор. А это совсем другая история.

Я как бы ни про какие GLR и т.п. вообще ничего не говорю. Основная моя мысль в том сообщение вообще о другом. О том, что у автора данного генератора парсеров подобные тесты выложены аж на первую страницу. А у вас (при большом количестве заявление о "самом быстром") нет ни то, что на первой странице, но даже при заданном прямом вопросе форуме нельзя получить ответ. Это как бы не дело.

_>>

_>>It is sufficiently fast and does not require much memory. This is the fastest implementation of the Earley parser which I know of. If you know a faster one, please send me a message. It can parse 300K lines of C program per second on modern computers and allocates about 5MB memory for 10K line C program.

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

Не очень понял в чём суть претензии. Что такое многопоточный парсер и где можно глянуть на их примеры? ) Вроде как все известные мне компиляторы тоже однопоточные. )

P.S. А вообще классный проект у данного товарища. Грамматика задаётся в стиле yacc/bison, но при этом не в виде кодогенерации перед компиляцией, а в виде текстовой строки, которая парсится в рантайме и там же строится парсер. Т.е. можно менять грамматики на ходу и при этом оно по производительности отстаёт от бизона не на какие-то дикие цифры. Если бы мне сейчас надо было в каком-то проекте использовать парсер для нетривиальной (для простой то и Boost.Spirit сойдёт) грамматики, то первом делом опробовал бы этот продукт.
Re[31]: Опциональные типы
От: WolfHound  
Дата: 19.03.17 18:58
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну так и замечательно. Это же было бы странно для какого-то теста проделывать реальную сложную работу. А тут всё просто идеально: и простая грамматика и при этом одновременно один из самых популярных языков. Да и легко подобрать реальный тест (как сделано в обсуждаемом случае) с мегабайтным исходником.

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

_>Я как бы ни про какие GLR и т.п. вообще ничего не говорю. Основная моя мысль в том сообщение вообще о другом. О том, что у автора данного генератора парсеров подобные тесты выложены аж на первую страницу. А у вас (при большом количестве заявление о "самом быстром") нет ни то, что на первой странице, но даже при заданном прямом вопросе форуме нельзя получить ответ. Это как бы не дело.

Хоть одну цитату про самый быстрый в студию.

_>Не очень понял в чём суть претензии. Что такое многопоточный парсер и где можно глянуть на их примеры? ) Вроде как все известные мне компиляторы тоже однопоточные. )

Да примерно все парсеры многопоточные в том смысле что можно запустить несколько потоков которые будут разбирать разные тексты.
Честно говоря, я не припомню какой ещё парсер так не может.
Но в данном случае судя по всему можно разбирать только один текст в одном процессе. Если захочешь разбирать несколько текстов одновременно тебе придётся поднять по процессу на каждый текст.
Ибо там вся логика на кучу изменяемых глобальных переменных завязана.
И публичный API тоже завязан на использование глобальных переменных.
Например, эта функция подразумевает что её пользователь заведёт глобальное состояние:
int
yaep_read_grammar (struct grammar *g, int strict_p,
           const char *(*read_terminal) (int *code),
           const char *(*read_rule) (const char ***rhs,
                         const char **abs_node,
                         int *anode_cost,
int **transl))


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

Ну и не нужно забывать про то что этот парсер имеет лицензию GNU GPL v2. Что делает его неприемлемым для очень большого количества проектов.

_>P.S. А вообще классный проект у данного товарища. Грамматика задаётся в стиле yacc/bison, но при этом не в виде кодогенерации перед компиляцией, а в виде текстовой строки, которая парсится в рантайме и там же строится парсер. Т.е. можно менять грамматики на ходу и при этом оно по производительности отстаёт от бизона не на какие-то дикие цифры. Если бы мне сейчас надо было в каком-то проекте использовать парсер для нетривиальной (для простой то и Boost.Spirit сойдёт) грамматики, то первом делом опробовал бы этот продукт.

И очень бы об это пожалел.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[32]: Опциональные типы
От: alex_public  
Дата: 19.03.17 19:29
Оценка:
Здравствуйте, WolfHound, Вы писали:

_>>Ну так и замечательно. Это же было бы странно для какого-то теста проделывать реальную сложную работу. А тут всё просто идеально: и простая грамматика и при этом одновременно один из самых популярных языков. Да и легко подобрать реальный тест (как сделано в обсуждаемом случае) с мегабайтным исходником.

WH>Проблема в том, что простая грамматика ничего не говорит о том, как оно будет себя вести на более сложных. Или просто описанных не так как любит алгоритм. Например, ANTLR’у 4 очень сильно плохеет если грамматику задать немного не так как он любит.

И? Это повод не знать как оно себя ведёт даже на простой грамматике? )

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

_>>Я как бы ни про какие GLR и т.п. вообще ничего не говорю. Основная моя мысль в том сообщение вообще о другом. О том, что у автора данного генератора парсеров подобные тесты выложены аж на первую страницу. А у вас (при большом количестве заявление о "самом быстром") нет ни то, что на первой странице, но даже при заданном прямом вопросе форуме нельзя получить ответ. Это как бы не дело.

WH>Хоть одну цитату про самый быстрый в студию.

Ну вот прямо в этой темке чуть выше можно прочитать "лучший в мире генератор парсеров". Ну да, формально конечно лучший!="самый быстрый", хотя мне лично не очень понятно какие ещё метрики для парсера могут быть более важными.

_>>Не очень понял в чём суть претензии. Что такое многопоточный парсер и где можно глянуть на их примеры? ) Вроде как все известные мне компиляторы тоже однопоточные. )

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

А, в смысле разные тексты. Тогда понятно. )

WH>Но в данном случае судя по всему можно разбирать только один текст в одном процессе. Если захочешь разбирать несколько текстов одновременно тебе придётся поднять по процессу на каждый текст.


С чего ты взял? Я конечно там по исходникам не лазил, но судя по примеру на первой странице там всё хранится в отдельных переменных. Состояние парсинга хранится в grammar (создаваемым earley_create_grammar, так что их может быть сколько угодно), а результат в дереве earley_tree_node.

WH>Ибо там вся логика на кучу изменяемых глобальных переменных завязана.

WH>И публичный API тоже завязан на использование глобальных переменных.
WH>Например, эта функция подразумевает что её пользователь заведёт глобальное состояние:
WH>
WH>int
WH>yaep_read_grammar (struct grammar *g, int strict_p,
WH>           const char *(*read_terminal) (int *code),
WH>           const char *(*read_rule) (const char ***rhs,
WH>                         const char **abs_node,
WH>                         int *anode_cost,
WH>int **transl))
WH>


Что-то я не вижу ничего подобного. )

WH>В общем для того чтобы этот проект можно было использовать нужен очень глубокий рефакторинг и интерфейса и реализации.

WH>Ну и не нужно забывать про то что этот парсер имеет лицензию GNU GPL v2. Что делает его неприемлемым для очень большого количества проектов.

Эмм, может мы на разные проекты смотрим? ))) Потому что у того, на что смотрю я, на первой же странице написано "YAEP is licensed under LGPL v.2.".
Re[33]: Опциональные типы
От: WolfHound  
Дата: 19.03.17 19:51
Оценка:
Здравствуйте, alex_public, Вы писали:

WH>>Но в данном случае судя по всему можно разбирать только один текст в одном процессе. Если захочешь разбирать несколько текстов одновременно тебе придётся поднять по процессу на каждый текст.

_>С чего ты взял? Я конечно там по исходникам не лазил, но судя по примеру на первой странице там всё хранится в отдельных переменных. Состояние парсинга хранится в grammar (создаваемым earley_create_grammar, так что их может быть сколько угодно), а результат в дереве earley_tree_node.
Ты, не поверишь. Я код прочитал.
Открываешь код yaep_parse и наслаждаешься.
https://github.com/vnmakarov/yaep/blob/master/src/yaep.c#L5904
Это всё инициализация глобальных переменных. Плюс куча функций с суффиксом _init тоже инициализирует глобальные переменные.
Да просто поищи static и увидишь сколько там глобальных переменных.

WH>>Ибо там вся логика на кучу изменяемых глобальных переменных завязана.

WH>>И публичный API тоже завязан на использование глобальных переменных.
WH>>Например, эта функция подразумевает что её пользователь заведёт глобальное состояние:
WH>>
WH>>int
WH>>yaep_read_grammar (struct grammar *g, int strict_p,
WH>>           const char *(*read_terminal) (int *code),
WH>>           const char *(*read_rule) (const char ***rhs,
WH>>                         const char **abs_node,
WH>>                         int *anode_cost,
WH>>int **transl))
WH>>

_>Что-то я не вижу ничего подобного. )
А как по-твоему могут работать коллбеки read_terminal и read_rule?

_>Эмм, может мы на разные проекты смотрим? ))) Потому что у того, на что смотрю я, на первой же странице написано "YAEP is licensed under LGPL v.2.".

Открываем
https://github.com/vnmakarov/yaep/blob/master/src/yaep.c

This is part of YAEP (Yet Another Earley Parser) implementation; you can
redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation; either
version 2, or (at your option) any later version.

В каком из двух мест врёт автор?
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[34]: Опциональные типы
От: alex_public  
Дата: 20.03.17 01:39
Оценка:
Здравствуйте, WolfHound, Вы писали:

_>>С чего ты взял? Я конечно там по исходникам не лазил, но судя по примеру на первой странице там всё хранится в отдельных переменных. Состояние парсинга хранится в grammar (создаваемым earley_create_grammar, так что их может быть сколько угодно), а результат в дереве earley_tree_node.

WH>Ты, не поверишь. Я код прочитал.
WH>Открываешь код yaep_parse и наслаждаешься.
WH>https://github.com/vnmakarov/yaep/blob/master/src/yaep.c#L5904
WH>Это всё инициализация глобальных переменных. Плюс куча функций с суффиксом _init тоже инициализирует глобальные переменные.
WH>Да просто поищи static и увидишь сколько там глобальных переменных.

Эх, пришлось залезть в исходники... Да, ты прав. ) Странно это у него как-то всё сделано. Внешний api вроде как нормальный многопоточный, а при вызове функции начинаем первым делам устанавливать переданные параметры в глобальные переменные — жесть. ))) Хотя у него проект разрабатывался как компилятор, так что понятно откуда такие замашки — компиляторы то все обычно однопоточные. )

Ну и в любом случае это никак не влияет на заявленные им параметры быстродействия. )

_>>Эмм, может мы на разные проекты смотрим? ))) Потому что у того, на что смотрю я, на первой же странице написано "YAEP is licensed under LGPL v.2.".

WH>Открываем
WH>https://github.com/vnmakarov/yaep/blob/master/src/yaep.c
WH>

WH> This is part of YAEP (Yet Another Earley Parser) implementation; you can
WH> redistribute it and/or modify it under the terms of the GNU General
WH> Public License as published by the Free Software Foundation; either
WH> version 2, or (at your option) any later version.

WH>В каком из двух мест врёт автор?

О, ещё один его косяк. Но вообще я склонен думать что всё же LGPL у него, т.к. шапка в подобных файлах обычно вставляет вообще автоматом. А вот текст заглавной страницы всё же пишут продумывая... )

Но это опять же всё не имеет никакого отношения к сути нашей дискуссии. ) А вот на то, что имеет, ты отвечать явно не очень хочешь... )
Re[23]: Опциональные типы
От: Klapaucius  
Дата: 27.03.17 07:51
Оценка: 21 (1)
Здравствуйте, WolfHound, Вы писали:

WH>1)Ты очень вольно интерпретируешь слово зависит.

WH>Тип Vec не параметризуется терминалом. А значит зависимым не является просто по определению.
WH>Nat в данном случае поднимается на уровень рода, а его значения на уровень типа.

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

WH>2)Попробуй вернуть этот вектор в функцию main таким образом, чтобы тип сохранился.


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

использую пакет singletons
{-# LANGUAGE PolyKinds, DataKinds, TypeFamilies, GADTs #-}
{-# LANGUAGE TypeOperators, NPlusKPatterns #-}
{-# LANGUAGE DeriveFoldable, StandaloneDeriving, TypeApplications #-}
{-# LANGUAGE TemplateHaskell #-} 

import Data.Singletons
import Data.Singletons.TH

import Text.Read (readMaybe)
import Data.Kind (Type)
import qualified Data.Foldable as F

data Nat = Z | S Nat deriving Show

intToNat 0 = Z
intToNat (n + 1) = S (intToNat n)

genSingletons [''Nat]

-- генерирует синглетоны для Nat:

-- data instance Sing (n :: Nat) where
--     SZ :: Sing Z
--     SS :: Sing n -> Sing (S n)

-- instance SingKind Nat where
--     type DemoteRep Nat = Nat

--     fromSing SZ = Z
--     fromSing (SS b) = S (fromSing b)

--     toSing Z = SomeSing SZ
--     toSing (S b) = case toSing b :: SomeSing Nat of
--           SomeSing c -> SomeSing (SS c)

data Vect :: Nat -> Type -> Type where
   V0 :: Vect Z x
   (:>) :: x -> Vect n x -> Vect (S n) x

deriving instance Foldable (Vect n) 

infixr 5 :>

getInt :: IO Int
getInt = do
  resp <- getLine
  case readMaybe @Int resp of
     Just value -> pure value
     Nothing -> do
       putStrLn "error"
       getInt

makeVect :: Sing (size :: Nat) -> a -> Vect size a
makeVect SZ _ = V0
makeVect (SS x) v = v :> makeVect x v

zipVect :: Vect size a -> Vect size b -> Vect size (a, b)
zipVect V0 V0 = V0
zipVect (x1 :> v1) (x2 :> v2) = (x1, x2) :> zipVect v1 v2

main :: IO ()
main = do
  putStrLn "Hello world"
  size <- getInt
  -- нету "голых" экзистенциальных типов, 
  -- работать с синглетоном числа придется только в континьюэйшене
  withSomeSing (intToNat size) $ \ssize -> do
    let vect1 = makeVect ssize size
    let vect2 = makeVect ssize "^_^"
    -- let vect2 = makeVect (SS ssize) "^_^" -- вызовет ошибку
    print . F.toList $ vect1
    print . F.toList $ vect2
    print . F.toList $ zipVect vect1 vect2
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[35]: Опциональные типы
От: vdimas Россия  
Дата: 29.05.17 03:25
Оценка:
Здравствуйте, WolfHound, Вы писали:

V>>Ты обещал, но так и не показал.

WH>Я показал ровно то что обещал. Твоя очередь демонстрировать ЗТ в хаскеле.

Показали через withSomeSing и do:
http://rsdn.org/forum/philosophy/6737439.1
Автор: Klapaucius
Дата: 27.03.17
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.