2006-03-15. The rest of this page is quite out of date.
More information is available here:
The Speedy YAML Cobble-Yourself-a-Slick-Little-Parser Kit. Created by WhyTheLuckyStiff.
Syck is a YAML parser written in C with the sole purpose of importing symbols into a scripting language's symbol table.
See the Syck HomePage for more.
As of 2003 Oct 14, Syck 0.42 has been released and is in active development. Inlines, anchors, aliases, single-quoted, double-quoted, plain strings and transfer methods are working. Indentation is quite good, most features work great at this point.
Extensions for Ruby, Python and PHP are working.
SourceForge CVS: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/yaml4r/syck/
Syck 0.42:
http://prdownloads.sourceforge.net/yaml4r/syck-0.42.tar.gz?download
CVS:
cvs -d:pserver:anonymous@rubyforge.org:/var/cvs/syck login cvs -z3 -d:pserver:anonymous@rubyforge.org:/var/cvs/syck co syck
The parser simply builds SyckNodes. The parser passes these nodes to a handler function, designated in the wrapper code. The handler returns a SYMID (an unsigned long), which references an entry in the language's symbol table.
In Ruby, the SYMID is identical to the VALUE id used internally. In Python and PHP (which I have extensions for), Syck uses a temporary symbol table which links SYMIDs to PyObject pointers or PHP's zval pointers. I imagine Perl would have SV pointers.
This work is not meant to compete with libyaml. Libyaml is just too big of a project for me to dig my claws into. I've tried looking at the code, but it's currently in an unbuildable state and I'm not sure where Neil left off.
Plus, the idea behind Syck is to keep it all small footprint. As SyckNodes are handled by the scripting language, the nodes are freed. The strings and pointers that comprised the node become housed by the scripting language. It's bloody fast, I'm telling you.
From CVS:
cvs co syck cd syck sh bootstrap ./configure make make check sudo make install
You don't need to have syck installed to install the Ruby module, but it does have to be `make'd. Since the syck Ruby module uses Ruby's own symbol table directly, the `extconf.rb' script copies only the pertinent source files and build the module from that:
cd syck/ext/ruby ruby install.rb config ruby install.rb setup sudo ruby install.rb install
Python requires libsyck installed:
cd syck/ext/python python setup.py build sudo python setup.py install
PHP requires libsyck and commandline PHP installed:
cd syck/ext/php sh make_module.sh sudo make install
Each of these extensions only has the `load' method, which accepts a YAML string.
SyckParser *parser; parser = syck_new_parser(); /* Parse here */ syck_free_parser(parser);
// Implicit typing on? (0 = NO; 1 = YES) syck_parser_implicit_typing(parser, 1); // Taguri expansion? (0 = NO; 1 = YES) syck_parser_taguri_expansion(parser, 0); // Node handler: SYMID my_node_loader( SyckParser *, SyckNode * ); syck_parser_handler(parser, my_node_loader); // Error handler: void my_syck_error( SyckParser *, char * ); syck_parser_error_handler(parser, my_syck_error); // Set FILE handle and read callback ( NULL for default callback ). syck_parser_file(parser, fp, NULL); // Set string IO and read callback ( NULL for default callback ). syck_parser_str(parser, str, len, my_string_read); // Parse, returning root symbol. root = syck_parse(parser);
typedef struct _syck_node SyckNode;
struct _syck_node {
// Symbol table ID
SYMID id;
// Underlying kind
enum syck_kind_tag kind;
// Fully qualified tag-uri for type
char *type_id;
// Anchor name
char *anchor;
union {
// Storage for map data
struct SyckMap {
SYMID *keys;
SYMID *values;
long capa;
long idx;
} *pairs;
// Storage for sequence data
struct SyckSeq {
SYMID *items;
long capa;
long idx;
} *list;
// Storage for string data
struct SyckStr {
char *ptr;
long len;
} *str;
} data;
};