to post messages and comments.

← All posts tagged yaml

Переоценил я 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, то смысла нет, но некоторые движки на всякий пожарный всё равно экранируют.

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 работает только в закавыченных строках.