to post messages and comments.

Переоценил я libyaml. Думал, универсальный движок и для JSON, и для YAML, но обнаружились нюансы.

Почему-то сложно оказалось добиться от libyaml форматированного JSON. Что-то я смутно припоминаю, что там чуть ли не реконструировать весь синтаксис оригинального документа можно было вместе с пробелами и табуляциями. Настолько можно всем порулить. И не нашёл, где это было. Надо отступы в поточный синтаксис (соответствующий подмножеству JSON) добавить, и никак. Только в блочном синтаксисе отступы есть. Хакнул libyaml, получил такое:

[4.0, "abc"
, {"x": -5.0, "z": 20.0
}
]

Скаляры где-то в другом буфере копятся. Если пытаться делать переносы перед ними, то перед «, {"x"» становится больше переносов.

Утверждается, что YAML синтаксически — надмножество JSON, и если загнать JSON в парсер YAML, то всё прочитается. На практике получается, что libyaml спотыкается на \/ в строке. Вообще говоря, экранировать прямую косую черту нужно только в HTML, чтоб там </script> ненароком не получился, а если Content-Type: application/json; charset=utf-8, то смысла нет, но некоторые движки на всякий пожарный всё равно экранируют.

Чтобы включать другие файлы друг в дружку, надо не только добавить конструктор тэга, но и заюзать разделитель `?`, иначе:
!include second.yml
!include third.yml
— даст результат типа: {second: !include third.yml}. Т.е. все данные после !include будут считаться связанными, вне зависимости от строчки, на которой они расположены. А вот с `?` уже не будет смотреть дальше.
При всей внешней простоте внутри yaml несколько кучерявый формат. Для того, чтобы убедиться, достаточно заглянуть в стандарт и посмотреть в примерах блоки справа.

Mapping nodes are somewhat tricky because their keys are unordered and must be unique.
Note that the YAML graph may include cycles, and a node may have more than one incoming edge.

А если ключ карты имеет сложную структуру и ссылается на родительский узел? Прямо Хаскель какой–то

rvelthuis.de
Пробую libyaml заинтерфейсить из Delphi 7. libyaml заточен под autotools. Накатал прокси для gcc, ld, ar, которые в окружении msys худо–бедно косят под одноимённые утилиты, но вызывают bcc32, ilink32 и tlib из Borland C++ 5.5 free command line tools. До конца не собралось, лень совершенствовать прокси, но дальше объектников мне всё равно не нужно. Код довольно чистый и по размерам объятный, так что кое–что удалось воплотить.
Я раньше таким способом серьёзные библиотеки не линковал. Всякие aspell подключались как dll'ки, JPEG и PNGImage сделаны кем–то другим, и я в код раньше не всматривался. Для себя я только во времена Borland Pascal линковал продукт работы binobj, а также tasm, но это всё не то.
Итак, я создал чистый юнит, и добавил в него $L для всех 8 .obj. Не компилируется, жалуется на unresolved externals, среди которых всякие _malloc, _realloc, _free, _strdup и прочие стандартные, которые, как выясняется, нередко дописываются прямо на Delphi так, чтобы они использовали тот же менеджер памяти, что и Delphi. Некоторые особо хардкорные вещи с varargs импортируются из msvcrt.dll. У меня всё из разных мест.
Есть возможность из Delphi немного изменить реализацию. Например, в libyaml используются fread и fwrite, но ничего кроме этого с файлами не делается, и я предоставил такую реализацию, которая читает и пишет в Classes.TStream вместо FILE*.
Далее, среди unresolved externals числятся также и все внутренние зависимости. То есть, если я объявляю procedure _yaml_траляля(ололо); cdecl; external;, это решает проблему. Сложно сказать, чей косяк. В C с импортами в заголовках всё тяжело. Связывание может быть статическим, динамическим, при динамическом связывании заголовок может подключаться как при компиляции собственно dll, так и при компиляции программ, её использующих, и эти три варианта использования нужно умножить на варианты компиляторов, чтобы получить многообразие ключевых слов для экспорта. autotools предоставляют для этих целей автоматически подобранные defin'ы, но libyaml их не использует, а применяет свой костылик, который не описывает мой случай. Я пытался менять хедер, но то ли я не подобрал ключевое слово, то ли в Delphi 7 так и должно быть, внутренние связи между .obj мне пришлось все объявить в паснике, который эти .obj подключает, и только тогда всё собралось. Тонкую привязку я уже почти сделал, а эти внутренние зависимости как раз неотъемлемая часть тонкой привязки.
Странно, но если сделать TLIB'ом .lib, Delphi его не подключит. Только одиночные .obj.

gunsmoker.ru
GunSmoker, когда подключал статическую библиотеку к Delphi, собирая динамическую, не так уж и прогадал.

interix-wgcc.sourceforge.net — gcc-мимикрирующая оболочка для MSVC, довольно продвинутая. Downloads куда–то делся, но можно скачать исходники.

octagram.name

Если кому надо, пока новая версия OpenMod'а ещё не готова, здесь можно взять агильные структуры (словари, последовательности, боксы для строк, чисел и boolean) и парсер подмножества YAML. Пригодится тем, кому надо на InnoSetup PascalScript написать что–нибудь эдакое.

Первая попытка реализовать парсер подмножества YAML на InnoSetup. Парсит, похоже, корректно, но 8 минут обрабатывать 383Кбайта — это много для инициализации инсталлятора. Буду переделывать с посимвольных конечных автоматов на построчную реализацию с использованием Pos, Copy, TrimLeft, ...

Не может не радовать, что затея с реализацией списков, словарей и боксов для строк и интов поверх TStringList–таки работает

Мыкался с этим #YAML, решил, что нужно строки по возможности оставлять как есть, а в том случае, если их нельзя вписать как есть из–за индикаторов, вставлять закавыченные.

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

Генерю сейчас так: octagram.name

Это валидный YAML. Пожалуй, пора теперь парсер на PascalScript уже делать.

Что–то не понимаю я, как, не используя кавычек, вводить символы :, " и прочие. Экранирование типа \x22 работает только в закавыченных строках.

YAML просто покоряет.... Поработав 2 дня с YAML (до этого никогда с ним не работал) понял на сколько сложен и избыточен XML для описания простых структур данных. Мне нравится :)

В этом сообщении juick.com проскальзывает типичное обвинение в чем-то того, что само по себе такого не представляет и представлять в силу своей сущности не может. Нет, разумеется, сам MXML как представитель xml-based languages, никак не является причиной текущей плачевной ситуации с ним во flex. И сам вопрос "какие преимущества у YAML над MXML в контексте Flex compiler?" звучит немного, без раскрытия, странно — потому что и тот, и другой всего лишь язык разметки — и никак не влияет на то, как же оно в итоге будет интерпретировано. Отставя в сторону туманные и безосновательные рассуждения о легкости парсинга и изначальном проектировании YAML для удобного маршалинга (он сам умеет refs и т. п.) в сухом остатке мы имеем легкость чтения — он чище и нет леса тегов — тот факт, что wiki-форматированный текст читается и правится руками в разы легче, чем xhtml-форматированный вряд ли кто-то будет оспаривать.

А теперь касательно того, почему была написана фраза "сам flex compiler неправильный". Знаете ли вы, как реализованы контейнеры во flex и как layout manager получает компоненты для раскладки? Контейнер (spark Group, ваш самописные и что угодно еще) имеет некое default property (должно называться mxmlContent, так как в Adobe не знают что такое интерфейсы и это имя свойства зашито в mx.states.* классах) с типом Array (компилятор не поддерживает векторы, поэтому должен быть только массив, если у вас есть states), которое инициализируется детьми этого контейнера в MXML. layout manager получает компоненты для раскладки через интерфейс (контейнер должен его реализовывать) — что-то типа getElementAt.

Вроде все нормально, да? Плевать на лишнее потребление памяти, плевать на совершение лишней работы в runtime (имею ввиду, что компилятор не должен делать лишний массив с детьми, а сам сразу генерировать код по добавлению детей и некой их обработке), плевать на увеличение размера swf.

А теперь давайте введем новый layout. Перенесемся в то время, когда не было constraints (CanvasLayout). Что было сделано? В UIComponent добавили left/right/top/bottom.
А теперь давайте введем новый layout — мы хотим нормальный GridBagLayout ( download.oracle.com ) Что мы сделаем? Добавим в UIComponent новое свойство gridConstraints.
А теперь давайте введем новый layout...

А можем ли мы не вводить свойства в UIComponent, а аккуратно рядышком в MXML указать его? Не можем. Проблема в том, что MXML сейчас, по части контейнеров (и даже практически во всем, кроме нового синтаксиса состояний в flex 4), представляет собой прямое отражение на AST. Где декларативность? Декларативность, это когда я устанавливая для контейнера некий layout автоматом получаю некое изменение семантики в контексте. Да, черт возьми, если уж говорится о декларативности, то это должна быть декларативность, а не маппер XML на ActionScript. Если говорится о декларативности, то я должен быть в состоянии описать декларативно сложный интерфейс без десятков H/V боксов. У вас не получится написать такой же красивый логичный xml, какой генерируется каким-нибудь gui builder типа IntelliJ IDEA, потому что mxml в данном случае будет тем самым маппером.

Хотя, постойте, нам же ничего не мешает считать каждый нечетный элемент массива компонентом, а каждый четный его constraints. Хм, чем-то пахнет.

wiki.github.com Представьте, как будет удобно и красиво иметь вместо xml-based MXML такой вот YAML для описания UI (разумеется, он должен генерироваться gui designer, но и декларативность такая должна быть) ;)

То ли руки не из того места, то ли понимание начисто отсутствует... Вместо yaml-cpp решил использовать yaml-core ("fast" YAML), и в студии нормально, а заставить собираться в C::B не получается. Не силён я в параметрах командной строки (в данном случае — параметрах проекта). Точнее даже как — библиотеки я собрал (отладочную и для выпуска), а в примере использовать не получается. В студии — всё нормально. И вроде всё правильно, и YAML_DECLARE_STATIC написан, и компоновщику библиотека указана. И вроде бы даже собирает, но на компоновке валится. Буду разбираться.

Так, на дохленьком железе 10000 узлов добавляются за 1.8 с, а парсятся за 35.44. В общем надо будет проверить на нормальной машине, но всё-таки — для почти мегабайтного результирующего файла думаю, что неплохой результат. Если интересно — парсил/генерил с помощью yaml-cpp (последний stable). В svn у них вроде чего-то ещё поправлено, надо будет посмотреть.
Да, у борланда очень своеобразный компилятор, а C::B как и раньше — самое то для "быстро попробовать".